﻿Imports System
Imports System.Collections
Imports System.Collections.Generic
Imports System.Collections.ObjectModel
Imports System.Diagnostics
Imports System.Globalization
Imports System.Reflection
Imports System.Runtime.CompilerServices
Imports System.Runtime.InteropServices
Imports System.Threading
Imports System.Transactions
Imports System.Workflow.ComponentModel
Imports System.Workflow.Runtime.DebugEngine
Imports System.Workflow.Runtime.Hosting

Namespace System.Workflow.Runtime
    Friend NotInheritable Class WorkflowExecutor
        Implements IWorkflowCoreRuntime, IServiceProvider
        ' Events
        Private Custom Event _workflowExecutionEvent As EventHandler([Of] WorkflowExecutionEventArgs)
        Friend Custom Event WorkflowExecutionEvent As EventHandler([Of] WorkflowExecutionEventArgs)

        ' Methods
        Shared Sub New()
            DependencyProperty.RegisterAsKnown(WorkflowExecutor.ContextIdProperty, &H33, PropertyValidity.Reexecute)
            DependencyProperty.RegisterAsKnown(WorkflowExecutor.IsSuspensionRequestedProperty, &H34, PropertyValidity.Uninitialize)
            DependencyProperty.RegisterAsKnown(WorkflowExecutor.TrackingCallingStateProperty, &H35, PropertyValidity.Uninitialize)
            DependencyProperty.RegisterAsKnown(WorkflowExecutor.TrackingListenerBrokerProperty, &H36, PropertyValidity.Uninitialize)
            DependencyProperty.RegisterAsKnown(WorkflowExecutor.IsIdleProperty, &H38, PropertyValidity.Uninitialize)
            DependencyProperty.RegisterAsKnown(Scheduler.NormalPriorityEntriesQueueProperty, &H3D, PropertyValidity.Uninitialize)
            DependencyProperty.RegisterAsKnown(Scheduler.HighPriorityEntriesQueueProperty, &H3E, PropertyValidity.Uninitialize)
            DependencyProperty.RegisterAsKnown(WorkflowQueuingService.LocalPersistedQueueStatesProperty, &H3F, PropertyValidity.Reexecute)
            DependencyProperty.RegisterAsKnown(WorkflowQueuingService.RootPersistedQueueStatesProperty, &H40, PropertyValidity.Reexecute)
            DependencyProperty.RegisterAsKnown(CorrelationTokenCollection.CorrelationTokenCollectionProperty, &H41, PropertyValidity.Always)
            DependencyProperty.RegisterAsKnown(CorrelationToken.NameProperty, &H43, PropertyValidity.Uninitialize)
            DependencyProperty.RegisterAsKnown(CorrelationToken.OwnerActivityNameProperty, &H44, PropertyValidity.Uninitialize)
            DependencyProperty.RegisterAsKnown(CorrelationToken.PropertiesProperty, &H45, PropertyValidity.Uninitialize)
            DependencyProperty.RegisterAsKnown(CorrelationToken.SubscriptionsProperty, 70, PropertyValidity.Uninitialize)
            DependencyProperty.RegisterAsKnown(CorrelationToken.InitializedProperty, &H47, PropertyValidity.Uninitialize)
            DependencyProperty.RegisterAsKnown(WorkflowDefinitionDispenser.WorkflowDefinitionHashCodeProperty, 80, PropertyValidity.Reexecute)
            DependencyProperty.RegisterAsKnown(WorkflowExecutor.WorkflowInstanceIdProperty, &H66, PropertyValidity.Reexecute)
            DependencyProperty.RegisterAsKnown(WorkflowExecutor.IsBlockedProperty, &H67, PropertyValidity.Reexecute)
            DependencyProperty.RegisterAsKnown(WorkflowExecutor.WorkflowStatusProperty, &H68, PropertyValidity.Reexecute)
            DependencyProperty.RegisterAsKnown(WorkflowExecutor.SuspendOrTerminateInfoProperty, &H69, PropertyValidity.Reexecute)
            WorkflowExecutor.workflowDebuggingDisabled = WorkflowExecutor.disableWorkflowDebugging.Enabled
        End Sub

        Friend Sub New(ByVal instanceId As Guid)
            Me._executorLock = LockFactory.CreateWorkflowExecutorLock(instanceId)
            Me._msgDeliveryLock = LockFactory.CreateWorkflowMessageDeliveryLock(instanceId)
            Me.stateChangedSincePersistence = True
            If Not WorkflowExecutor.workflowDebuggingDisabled Then
                Me._workflowDebuggerService = New WorkflowDebuggerService(Me)
            End If
        End Sub

        Private Sub _setInArgsOnCompanion(ByVal namedInArguments As IDictionary([Of] String, Object))
            If (Not namedInArguments Is Nothing) Then
                Dim str As String
                For Each str In namedInArguments.Keys
                    Dim property As PropertyInfo = Me.WorkflowDefinition.GetType.GetProperty(str)
                    If ((Not [property] Is Nothing) AndAlso [property].CanWrite) Then
                        Try 
                            [property].SetValue(Me.rootActivity, namedInArguments.Item(str), Nothing)
                            [Continue] For
                        Catch exception As ArgumentException
                            Throw New ArgumentException(ExecutionStringManager.InvalidWorkflowParameterValue, str, exception)
                        End Try
                    End If
                    Throw New ArgumentException(String.Format(CultureInfo.CurrentCulture, ExecutionStringManager.SemanticErrorInvalidNamedParameter, New Object() { Me.WorkflowDefinition.Name, str }))
                Next
            End If
        End Sub

        Friend Sub Abort()
            WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 0, "Workflow Runtime: WorkflowExecutor::Abort : Got a abort request for instance {0}", New Object() { Me.InstanceIdString })
            Try 
                [Using] Me._executorLock.Enter
                    Me.Scheduler.AbortOrTerminateRequested = True
                    Me.Scheduler.CanRun = False
                    [Using] New SchedulerLockGuard(Me._schedulerLock, Me)
                        [Using] Me._msgDeliveryLock.Enter
                            [Using] New ServiceEnvironment(Me.rootActivity)
                                If Not Me.IsInstanceValid Then
                                    Throw New InvalidOperationException(ExecutionStringManager.WorkflowNotValid)
                                End If
                                Me.AbortOnIdle
                            End [Using]
                        End [Using]
                    End [Using]
                End [Using]
            Catch exception As Exception
                WorkflowTrace.Runtime.TraceEvent(TraceEventType.Error, 0, "Workflow Runtime: WorkflowExecutor: Abort attempt on instance '{0}' threw an exception '{1}' at {2}", New Object() { Me.InstanceIdString, exception.Message, exception.StackTrace })
                Throw
            End Try
        End Sub

        Friend Sub AbortOnIdle()
            If Me.IsInstanceValid Then
                Me.FireWorkflowExecutionEvent(Me, WorkflowEventInternal.Aborting)
                Me.TimerQueue.SuspendDelivery
                Me.Scheduler.CanRun = False
                WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 0, "Workflow Runtime: WorkflowExecutor: Aborting instance {0}", New Object() { Me.InstanceIdString })
                Try 
                    If (Not Me.currentAtomicActivity Is Nothing) Then
                        Me.RollbackTransaction(Nothing, Me.currentAtomicActivity)
                        Me.currentAtomicActivity = Nothing
                    End If
                    Me.ResourceManager.ClearAllBatchedWork
                    Dim workflowPersistenceService As WorkflowPersistenceService = Me.WorkflowRuntime.WorkflowPersistenceService
                    If (Not workflowPersistenceService Is Nothing) Then
                        workflowPersistenceService.UnlockWorkflowInstanceState(If(Me.attemptedRootDispose, Nothing, Me.rootActivity))
                        If Me.HasNonEmptyWorkBatch Then
                            Me.CommitTransaction(Me.rootActivity)
                        End If
                    End If
                Catch exception As Exception
                    If WorkflowExecutor.IsIrrecoverableException(exception) Then
                        Throw
                    End If
                Finally
                    Me.IsInstanceValid = False
                    Me.DisposeRootActivity(True)
                    If (Not Me.currentAtomicActivity Is Nothing) Then
                        Me.atomicActivityEvent.Set
                        Me.atomicActivityEvent.Close
                    End If
                    Me.FireEventAfterSchedulerLockDrop(WorkflowEventInternal.Aborted)
                End Try
            End If
        End Sub

        Private Sub AddItemToBeScheduledLater(ByVal atomicActivity As Activity, ByVal item As SchedulableItem)
            If ((Not atomicActivity Is Nothing) AndAlso atomicActivity.SupportsTransaction) Then
                Dim properties As TransactionalProperties = DirectCast(atomicActivity.GetValue(WorkflowExecutor.TransactionalPropertiesProperty), TransactionalProperties)
                If (Not properties Is Nothing) Then
                    SyncLock properties
                        Dim itemsToBeScheduledAtCompletion As List([Of] SchedulableItem) = Nothing
                        itemsToBeScheduledAtCompletion = properties.ItemsToBeScheduledAtCompletion
                        If (itemsToBeScheduledAtCompletion Is Nothing) Then
                            itemsToBeScheduledAtCompletion = New List([Of] SchedulableItem)
                            properties.ItemsToBeScheduledAtCompletion = itemsToBeScheduledAtCompletion
                        End If
                        itemsToBeScheduledAtCompletion.Add(item)
                    End SyncLock
                End If
            End If
        End Sub

        Friend Sub ApplyWorkflowChanges(ByVal workflowChanges As WorkflowChanges)
            If (workflowChanges Is Nothing) Then
                Throw New ArgumentNullException("workflowChanges")
            End If
            If Not Me.IsInstanceValid Then
                Throw New InvalidOperationException(ExecutionStringManager.WorkflowNotValid)
            End If
            If (Not Me.currentAtomicActivity Is Nothing) Then
                Throw New InvalidOperationException(ExecutionStringManager.Error_InsideAtomicScope)
            End If
            Try 
                [Using] New ScheduleWork(Me)
                    [Using] Me._executorLock.Enter
                        If Not Me.IsInstanceValid Then
                            Throw New InvalidOperationException(ExecutionStringManager.WorkflowNotValid)
                        End If
                        Me.Scheduler.CanRun = False
                        [Using] New SchedulerLockGuard(Me._schedulerLock, Me)
                            [Using] New ServiceEnvironment(Me.rootActivity)
                                Dim flag As Boolean = False
                                If Not Me.IsInstanceValid Then
                                    Throw New InvalidOperationException(ExecutionStringManager.WorkflowNotValid)
                                End If
                                Try 
                                    Select Case Me.WorkflowStatus
                                        Case WorkflowStatus.Completed, WorkflowStatus.Terminated
                                            Throw New InvalidOperationException(ExecutionStringManager.InvalidOperationRequest)
                                        Case WorkflowStatus.Suspended
                                            flag = False
                                            Exit Select
                                        Case Else
                                            Me.SuspendOnIdle(Nothing)
                                            flag = True
                                            Exit Select
                                    End Select
                                    workflowChanges.ApplyTo(Me.rootActivity)
                                Finally
                                    If flag Then
                                        Me.ResumeOnIdle(True)
                                    End If
                                End Try
                            End [Using]
                        End [Using]
                    End [Using]
                End [Using]
            Catch exception As Exception
                WorkflowTrace.Runtime.TraceEvent(TraceEventType.Error, 0, "Workflow Runtime: WorkflowExecutor: dynamic update attempt from outside on instance '{0}' threw an exception '{1}' at {2}", New Object() { Me.InstanceIdString, exception.Message, exception.StackTrace })
                Throw
            End Try
        End Sub

        Friend Shared Function CheckAndProcessTransactionAborted(ByVal transactionalProperties As TransactionalProperties) As Boolean
            If ((transactionalProperties.Transaction Is Nothing) OrElse (transactionalProperties.Transaction.TransactionInformation.Status = TransactionStatus.Aborted)) Then
                Select Case transactionalProperties.TransactionState
                    Case TransactionProcessState.Ok, TransactionProcessState.Aborted
                        transactionalProperties.TransactionState = TransactionProcessState.AbortProcessed
                        Throw New TransactionAbortedException
                    Case TransactionProcessState.AbortProcessed
                        Return True
                End Select
            End If
            Return False
        End Function

        Private Sub CommitTransaction(ByVal activityContext As Activity)
            If (Nothing Is Transaction.Current) Then
                Try 
                    Me.WorkflowRuntime.TransactionService.CommitWorkBatch(New CommitWorkBatchCallback(AddressOf Me.DoResourceManagerCommit))
                    Me.ResourceManager.Complete
                    Return
                Catch obj1 As Object
                    Me.ResourceManager.HandleFault
                    Throw
                End Try
            End If
            Dim transactionalProperties As TransactionalProperties = Nothing
            Dim flag As Boolean = (activityContext Is Me.currentAtomicActivity)
            If flag Then
                transactionalProperties = DirectCast(activityContext.GetValue(WorkflowExecutor.TransactionalPropertiesProperty), TransactionalProperties)
                If WorkflowExecutor.CheckAndProcessTransactionAborted(transactionalProperties) Then
                    Return
                End If
            End If
            Try 
                Me.WorkflowRuntime.TransactionService.CommitWorkBatch(New CommitWorkBatchCallback(AddressOf Me.DoResourceManagerCommit))
            Catch obj2 As Object
                Me.ResourceManager.HandleFault
                Throw
            Finally
                If flag Then
                    Me.DisposeTransactionScope(transactionalProperties)
                End If
            End Try
            If flag Then
                Try 
                    Dim transaction As CommittableTransaction = [TryCast](transactionalProperties.Transaction,CommittableTransaction)
                    If (Not Nothing Is transaction) Then
                        Try 
                            transaction.Commit
                        Catch obj3 As Object
                            Me.qService.PostPersist(False)
                            Throw
                        End Try
                        WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 0, String.Concat(New Object() { "Workflow Runtime: WorkflowExecutor: instanceId: ", Me.InstanceIdString, " .Committed CommittableTransaction ", transactionalProperties.Transaction.GetHashCode }))
                    End If
                    Dim transaction2 As DependentTransaction = [TryCast](transactionalProperties.Transaction,DependentTransaction)
                    If (Not Nothing Is transaction2) Then
                        Try 
                            transaction2.Complete
                        Catch obj4 As Object
                            Me.qService.PostPersist(False)
                            Throw
                        End Try
                        WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 0, String.Concat(New Object() { "Workflow Runtime: WorkflowExecutor: instanceId: ", Me.InstanceIdString, " .Completed DependentTransaction ", transactionalProperties.Transaction.GetHashCode }))
                    End If
                Catch obj5 As Object
                    Me.ResourceManager.HandleFault
                    Throw
                End Try
                Me.DisposeTransaction(activityContext)
                Me.currentAtomicActivity = Nothing
                WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 0, ("Workflow Runtime: WorkflowExecutor: instanceId: " & Me.InstanceIdString & "Reset CurrentAtomicActivity to null"))
            End If
            Me.ResourceManager.Complete
        End Sub

        Private Sub CreateTransaction(ByVal atomicActivity As Activity)
            Dim properties As New TransactionalProperties
            Dim options As New TransactionOptions
            Dim transactionOptions As WorkflowTransactionOptions = TransactedContextFilter.GetTransactionOptions(atomicActivity)
            options.IsolationLevel = transactionOptions.IsolationLevel
            If (options.IsolationLevel = IsolationLevel.Unspecified) Then
                options.IsolationLevel = IsolationLevel.Serializable
            End If
            options.Timeout = transactionOptions.TimeoutDuration
            Dim transaction As New CommittableTransaction(options)
            properties.Transaction = transaction
            WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 0, String.Concat(New Object() { "Workflow Runtime: WorkflowExecutor: instanceId: ", Me.InstanceIdString, " .Created enlistable transaction ", transaction.GetHashCode, " with timeout ", options.Timeout, ", isolation ", options.IsolationLevel }))
            properties.LocalQueuingService = New WorkflowQueuingService(Me.qService)
            atomicActivity.SetValue(WorkflowExecutor.TransactionalPropertiesProperty, properties)
            Me.currentAtomicActivity = atomicActivity
            Me.atomicActivityEvent = New ManualResetEvent(False)
            WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 0, ("Workflow Runtime: WorkflowExecutor: instanceId: " & Me.InstanceIdString & " .Set CurrentAtomicActivity to " & atomicActivity.Name))
        End Sub

        Friend Sub DeliverTimerSubscriptions()
            [Using] New ScheduleWork(Me)
                [Using] Me._executorLock.Enter
                    If Me.IsInstanceValid Then
                        [Using] Me.MessageDeliveryLock.Enter
                            [Using] New ServiceEnvironment(Me.rootActivity)
                                If Me.IsInstanceValid Then
                                    Dim timerQueue As TimerEventSubscriptionCollection = Me.TimerQueue
                                    Dim flag As Boolean = False
                                    Do While Not flag
                                        SyncLock timerQueue.SyncRoot
                                            Dim subscription As TimerEventSubscription = timerQueue.Peek
                                            If ((subscription Is Nothing) OrElse (subscription.ExpiresAt > DateTime.UtcNow)) Then
                                                flag = True
                                            Else
                                                WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "Delivering timer subscription for instance {0}", New Object() { Me.InstanceIdString })
                                                Me.stateChangedSincePersistence = True
                                                SyncLock Me.qService.SyncRoot
                                                    If Me.qService.Exists(subscription.QueueName) Then
                                                        Me.qService.EnqueueEvent(subscription.QueueName, subscription.SubscriptionId)
                                                    End If
                                                End SyncLock
                                                timerQueue.Dequeue
                                            End If
                                            [Continue] Do
                                        End SyncLock
                                    Loop
                                End If
                            End [Using]
                        End [Using]
                    End If
                End [Using]
            End [Using]
        End Sub

        <Conditional("DEBUG")> _
        Private Sub DiagnosticStackTrace(ByVal reason As String)
            Dim trace As New StackTrace(True)
            WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 0, "Workflow Runtime: WorkflowExecutor: InstanceId: {0} : {1} stack trace: {2}", New Object() { Me.InstanceIdString, reason, trace.ToString })
        End Sub

        Private Sub DisposeRootActivity(ByVal aborting As Boolean)
            Try 
                If Not Me.attemptedRootAECUnload Then
                    Me.attemptedRootAECUnload = True
                    Me.RootActivity.OnActivityExecutionContextUnload(Me)
                End If
                If Not Me.attemptedRootDispose Then
                    Me.attemptedRootDispose = True
                    Me.RootActivity.Dispose
                End If
            Catch exception1 As Exception
                If Not aborting Then
                    [Using] Me._msgDeliveryLock.Enter
                        Me.AbortOnIdle
                        Throw
                    End [Using]
                End If
            End Try
        End Sub

        Private Sub DisposeTransaction(ByVal atomicActivity As Activity)
            Dim properties As TransactionalProperties = DirectCast(atomicActivity.GetValue(WorkflowExecutor.TransactionalPropertiesProperty), TransactionalProperties)
            properties.Transaction.Dispose
            WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 0, String.Concat(New Object() { "Workflow Runtime: WorkflowExecutor: instanceId: ", Me.InstanceIdString, " .Disposed enlistable transaction ", properties.Transaction.GetHashCode }))
            properties.Transaction = Nothing
            properties.LocalQueuingService = Nothing
            properties.Transaction = Nothing
            Me.atomicActivityEvent.Set
            Me.atomicActivityEvent.Close
        End Sub

        Private Sub DisposeTransactionScope(ByVal transactionalProperties As TransactionalProperties)
            If (Not transactionalProperties.TransactionScope Is Nothing) Then
                transactionalProperties.TransactionScope.Complete
                transactionalProperties.TransactionScope.Dispose
                transactionalProperties.TransactionScope = Nothing
                WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 0, ("Workflow Runtime: WorkflowExecutor: instanceId: " & Me.InstanceIdString & "Left TransactionScope, Current atomic acitivity was " & If((Me.currentAtomicActivity Is Nothing), Nothing, Me.currentAtomicActivity.Name)))
            End If
        End Sub

        Private Sub DoResourceManagerCommit()
            If (Nothing Is Transaction.Current) Then
                Throw New Exception(ExecutionStringManager.NullAmbientTransaction)
            End If
            Me.ResourceManager.Commit
        End Sub

        Friend Sub EnqueueItem(ByVal queueName As IComparable, ByVal item As Object, ByVal pendingWork As IPendingWork, ByVal workItem As Object)
            [Using] New ScheduleWork(Me)
                Dim flag As Boolean = False
                If Not ServiceEnvironment.IsInServiceThread(Me.InstanceId) Then
                    flag = Me._schedulerLock.TryEnter
                End If
                Try 
                    [Using] Me.MessageDeliveryLock.Enter
                        If Not Me.IsInstanceValid Then
                            Throw New InvalidOperationException(ExecutionStringManager.WorkflowNotValid)
                        End If
                        If (flag OrElse ServiceEnvironment.IsInServiceThread(Me.InstanceId)) Then
                            [Using] New ServiceEnvironment(Me.RootActivity)
                                Me.qService.EnqueueEvent(queueName, item)
                                goto Label_008E
                            End [Using]
                        End If
                        If Me.qService.SafeEnqueueEvent(queueName, item) Then
                            ScheduleWork.NeedsService = True
                        End If
                    Label_008E:
                        If (Not pendingWork Is Nothing) Then
                            Me._resourceManager.BatchCollection.GetBatch(Me.rootActivity).Add(pendingWork, workItem)
                        End If
                        Me.stateChangedSincePersistence = True
                    End [Using]
                Finally
                    If flag Then
                        Me._schedulerLock.Exit
                    End If
                End Try
            End [Using]
        End Sub

        Friend Sub EnqueueItemOnIdle(ByVal queueName As IComparable, ByVal item As Object, ByVal pendingWork As IPendingWork, ByVal workItem As Object)
            [Using] New ScheduleWork(Me)
                [Using] Me._executorLock.Enter
                    If Not Me.IsInstanceValid Then
                        Throw New InvalidOperationException(ExecutionStringManager.WorkflowNotValid)
                    End If
                    [Using] guard As InstanceLockGuard = Me.MessageDeliveryLock.Enter
                        [Using] New ServiceEnvironment(Me.rootActivity)
                            If Me.IsInstanceValid Then
                                goto Label_006C
                            End If
                            Throw New InvalidOperationException(ExecutionStringManager.WorkflowNotValid)
                        Label_0052:
                            guard.Wait
                            If Not Me.IsInstanceValid Then
                                Throw New InvalidOperationException(ExecutionStringManager.WorkflowNotValid)
                            End If
                        Label_006C:
                            If Not Me.IsIdle Then
                                goto Label_0052
                            End If
                            If ((Me.WorkflowStatus = WorkflowStatus.Suspended) OrElse Not Me.Scheduler.CanRun) Then
                                Throw New InvalidOperationException(ExecutionStringManager.InvalidWaitForIdleOnSuspendedWorkflow)
                            End If
                            Try 
                                If (Not pendingWork Is Nothing) Then
                                    DirectCast(Me.rootActivity.GetValue(WorkflowExecutor.TransientBatchProperty), IWorkBatch).Add(pendingWork, workItem)
                                End If
                                Me.stateChangedSincePersistence = True
                                Me.qService.EnqueueEvent(queueName, item)
                            Finally
                                If Me.IsIdle Then
                                    guard.Pulse
                                End If
                            End Try
                        End [Using]
                    End [Using]
                End [Using]
            End [Using]
        End Sub

        Friend Sub ExceptionOccured(ByVal exp As Exception, ByVal currentActivity As Activity, ByVal originalActivityId As String)
            If (Not Me.ThrownException Is exp) Then
                Me.ThrownException = exp
                Me.activityThrowingException = currentActivity.QualifiedName
                originalActivityId = currentActivity.QualifiedName
            Else
                originalActivityId = Me.activityThrowingException
            End If
            Dim contextGuid As Guid = DirectCast(ContextActivityUtils.ContextActivity(currentActivity).GetValue(Activity.ActivityExecutionContextInfoProperty), ActivityExecutionContextInfo).ContextGuid
            Dim empty As Guid = Guid.Empty
            If (Not currentActivity.Parent Is Nothing) Then
                empty = DirectCast(ContextActivityUtils.ContextActivity(currentActivity.Parent).GetValue(Activity.ActivityExecutionContextInfoProperty), ActivityExecutionContextInfo).ContextGuid
            End If
            Me.FireExceptionOccured(exp, currentActivity.QualifiedName, originalActivityId, contextGuid, empty)
            [Using] New ServiceEnvironment(currentActivity)
                [Using] Me.SetCurrentActivity(currentActivity)
                    [Using] context As ActivityExecutionContext = New ActivityExecutionContext(currentActivity, True)
                        context.FaultActivity(exp)
                    End [Using]
                End [Using]
            End [Using]
            Me.RollbackTransaction(exp, currentActivity)
            If (TypeOf currentActivity Is TransactionScopeActivity OrElse TypeOf exp Is PersistenceException) Then
                Me.BatchCollection.RollbackBatch(currentActivity)
            End If
        End Sub

        Private Function FindExecutorToHandleException() As Activity
            Dim currentActivity As Activity = Me.CurrentActivity
            If (currentActivity Is Nothing) Then
                currentActivity = Me.rootActivity
            End If
            Return currentActivity
        End Function

        Private Sub FireActivityExecuting(ByVal sender As Object, ByVal activity As Activity)
            Dim e As New ActivityExecutingEventArgs(activity)
            Dim handler As EventHandler([Of] WorkflowExecutionEventArgs) = Me._workflowExecutionEvent
            If (Not handler Is Nothing) Then
                handler.Invoke(sender, e)
            End If
        End Sub

        Private Sub FireActivityStatusChange(ByVal sender As Object, ByVal activity As Activity)
            Dim e As New ActivityStatusChangeEventArgs(activity)
            Dim handler As EventHandler([Of] WorkflowExecutionEventArgs) = Me._workflowExecutionEvent
            If (Not handler Is Nothing) Then
                handler.Invoke(sender, e)
            End If
        End Sub

        Private Sub FireDynamicUpdateBegin(ByVal changeActions As IList([Of] WorkflowChangeAction))
            Dim handler As EventHandler([Of] WorkflowExecutionEventArgs) = Me._workflowExecutionEvent
            If (Not handler Is Nothing) Then
                handler.Invoke(Me, New DynamicUpdateEventArgs(changeActions, WorkflowEventInternal.DynamicChangeBegin))
            End If
        End Sub

        Private Sub FireDynamicUpdateCommit(ByVal changeActions As IList([Of] WorkflowChangeAction))
            Dim handler As EventHandler([Of] WorkflowExecutionEventArgs) = Me._workflowExecutionEvent
            If (Not handler Is Nothing) Then
                handler.Invoke(Me, New DynamicUpdateEventArgs(changeActions, WorkflowEventInternal.DynamicChangeCommit))
            End If
        End Sub

        Private Sub FireDynamicUpdateRollback(ByVal changeActions As IList([Of] WorkflowChangeAction))
            Dim handler As EventHandler([Of] WorkflowExecutionEventArgs) = Me._workflowExecutionEvent
            If (Not handler Is Nothing) Then
                handler.Invoke(Me, New DynamicUpdateEventArgs(changeActions, WorkflowEventInternal.DynamicChangeRollback))
            End If
        End Sub

        Private Sub FireEventAfterSchedulerLockDrop(ByVal workflowEventInternal As WorkflowEventInternal)
            Me.eventsToFireList.Add(New SchedulerLockGuardInfo(Me, workflowEventInternal))
        End Sub

        Private Sub FireEventAfterSchedulerLockDrop(ByVal workflowEventInternal As WorkflowEventInternal, ByVal eventInfo As Object)
            Me.eventsToFireList.Add(New SchedulerLockGuardInfo(Me, workflowEventInternal, eventInfo))
        End Sub

        Friend Sub FireExceptionOccured(ByVal e As Exception, ByVal currentActivityPath As String, ByVal originalActivityPath As String, ByVal contextGuid As Guid, ByVal parentContextGuid As Guid)
            Me.FireWorkflowException(e, currentActivityPath, originalActivityPath, contextGuid, parentContextGuid)
        End Sub

        Private Sub FireUserTrackPoint(ByVal activity As Activity, ByVal key As String, ByVal args As Object)
            Dim handler As EventHandler([Of] WorkflowExecutionEventArgs) = Me._workflowExecutionEvent
            If (Not handler Is Nothing) Then
                handler.Invoke(Me, New UserTrackPointEventArgs(activity, key, args))
            End If
        End Sub

        Private Sub FireWorkflowException(ByVal exception As Exception, ByVal currentPath As String, ByVal originalPath As String, ByVal contextGuid As Guid, ByVal parentContextGuid As Guid)
            Dim handler As EventHandler([Of] WorkflowExecutionEventArgs) = Me._workflowExecutionEvent
            If (Not handler Is Nothing) Then
                handler.Invoke(Me, New WorkflowExecutionExceptionEventArgs(exception, currentPath, originalPath, contextGuid, parentContextGuid))
            End If
        End Sub

        Friend Sub FireWorkflowExecutionEvent(ByVal sender As Object, ByVal eventType As WorkflowEventInternal)
            If (sender Is Nothing) Then
                sender = Me
            End If
            Dim handler As EventHandler([Of] WorkflowExecutionEventArgs) = Me._workflowExecutionEvent
            If (Not handler Is Nothing) Then
                handler.Invoke(sender, New WorkflowExecutionEventArgs(eventType))
            End If
        End Sub

        Friend Sub FireWorkflowHandlerInvokingEvent(ByVal sender As Object, ByVal eventType As WorkflowEventInternal, ByVal delegateHandler As Delegate)
            If (sender Is Nothing) Then
                sender = Me
            End If
            Dim handler As EventHandler([Of] WorkflowExecutionEventArgs) = Me._workflowExecutionEvent
            If (Not handler Is Nothing) Then
                handler.Invoke(sender, New WorkflowHandlerInvokingEventArgs(eventType, delegateHandler))
            End If
        End Sub

        Friend Sub FireWorkflowSuspended(ByVal [error] As String)
            Dim handler As EventHandler([Of] WorkflowExecutionEventArgs) = Me._workflowExecutionEvent
            If (Not handler Is Nothing) Then
                handler.Invoke(Me, New WorkflowExecutionSuspendedEventArgs([error]))
            End If
        End Sub

        Private Sub FireWorkflowSuspending(ByVal [error] As String)
            Dim handler As EventHandler([Of] WorkflowExecutionEventArgs) = Me._workflowExecutionEvent
            If (Not handler Is Nothing) Then
                handler.Invoke(Me, New WorkflowExecutionSuspendingEventArgs([error]))
            End If
        End Sub

        Friend Sub FireWorkflowTerminated(ByVal exception As Exception)
            Dim handler As EventHandler([Of] WorkflowExecutionEventArgs) = Me._workflowExecutionEvent
            If (Not handler Is Nothing) Then
                handler.Invoke(Me, New WorkflowExecutionTerminatedEventArgs(exception))
            End If
        End Sub

        Friend Sub FireWorkflowTerminated(ByVal [error] As String)
            Dim handler As EventHandler([Of] WorkflowExecutionEventArgs) = Me._workflowExecutionEvent
            If (Not handler Is Nothing) Then
                handler.Invoke(Me, New WorkflowExecutionTerminatedEventArgs([error]))
            End If
        End Sub

        Private Sub FireWorkflowTerminating(ByVal exception As Exception)
            Dim handler As EventHandler([Of] WorkflowExecutionEventArgs) = Me._workflowExecutionEvent
            If (Not handler Is Nothing) Then
                handler.Invoke(Me, New WorkflowExecutionTerminatingEventArgs(exception))
            End If
        End Sub

        Private Sub FireWorkflowTerminating(ByVal [error] As String)
            Dim handler As EventHandler([Of] WorkflowExecutionEventArgs) = Me._workflowExecutionEvent
            If (Not handler Is Nothing) Then
                handler.Invoke(Me, New WorkflowExecutionTerminatingEventArgs([error]))
            End If
        End Sub

        Friend Function GetContextActivityForId(ByVal stateId As Integer) As Activity
            If Me.subStateMap.ContainsKey(stateId) Then
                Return Me.subStateMap.Item(stateId)
            End If
            Return Nothing
        End Function

        Private Shared Function GetNestedExceptionMessage(ByVal exp As Exception) As String
            Dim message As String = ""
            Do While (Not exp Is Nothing)
                If (message = "") Then
                    message = exp.Message
                Else
                    message = (message & " " & exp.Message)
                End If
                exp = exp.InnerException
            Loop
            Return message
        End Function

        Private Function GetNewContextId() As Integer
            Dim num As Integer = (CInt(Me.rootActivity.GetValue(WorkflowExecutor.ContextIdProperty)) + 1)
            Me.rootActivity.SetValue(WorkflowExecutor.ContextIdProperty, num)
            Return num
        End Function

        Private Shared Function GetTransientBatch(ByVal dependencyObject As DependencyObject) As Object
            If (dependencyObject Is Nothing) Then
                Throw New ArgumentNullException("dependencyObject")
            End If
            If Not TypeOf dependencyObject Is Activity Then
                Throw New ArgumentException(String.Format(CultureInfo.CurrentCulture, ExecutionStringManager.InvalidArgumentType, New Object() { "dependencyObject", GetType(Activity).ToString }))
            End If
            Dim parent As Activity = DirectCast(dependencyObject, Activity)
            Dim executor As WorkflowExecutor = Nothing
            If (Not parent Is Nothing) Then
                executor = ContextActivityUtils.RetrieveWorkflowExecutor(parent)
            End If
            Do While (Not parent Is Nothing)
                Dim valueBase As IWorkBatch = [TryCast](parent.GetValueBase(WorkflowExecutor.TransientBatchProperty),IWorkBatch)
                If (Not valueBase Is Nothing) Then
                    Return valueBase
                End If
                If ((Not TransactedContextFilter.GetTransactionOptions(parent) Is Nothing) AndAlso (parent.ExecutionStatus = ActivityExecutionStatus.Executing)) Then
                    Return executor.BatchCollection.GetBatch(parent)
                End If
                If TypeOf parent Is CompositeActivity Then
                    Dim activity2 As Activity
                    For Each activity2 In DirectCast(parent, ISupportAlternateFlow).AlternateFlowActivities
                        If TypeOf activity2 Is FaultHandlerActivity Then
                            Return executor.BatchCollection.GetBatch(parent)
                        End If
                    Next
                End If
                If (parent Is executor.rootActivity) Then
                    Return executor.BatchCollection.GetBatch(parent)
                End If
                parent = parent.Parent
            Loop
            Return Nothing
        End Function

        Friend Function GetWorkflowDefinition(ByVal workflowContext As String) As Activity
            If (workflowContext Is Nothing) Then
                Throw New ArgumentNullException("workflowContext")
            End If
            Return Me.WorkflowDefinition
        End Function

        Friend Function GetWorkflowDefinitionClone(ByVal workflowContext As String) As Activity
            If (workflowContext Is Nothing) Then
                Throw New ArgumentNullException("workflowContext")
            End If
            Dim workflowDefinition As Activity = Me.WorkflowDefinition
            [Using] New WorkflowDefinitionLock(workflowDefinition)
                Return workflowDefinition.Clone
            End [Using]
        End Function

        Friend Function GetWorkflowNextTimerExpiration() As DateTime
            Dim time As DateTime
            [Using] Me._executorLock.Enter
                [Using] Me.MessageDeliveryLock.Enter
                    Dim subscription As TimerEventSubscription = Me.TimerQueue.Peek
                    time = If((subscription Is Nothing), DateTime.MaxValue, subscription.ExpiresAt)
                End [Using]
            End [Using]
            Return time
        End Function

        Friend Function GetWorkflowQueueInfos() As ReadOnlyCollection([Of] WorkflowQueueInfo)
            Dim list As New List([Of] WorkflowQueueInfo)
            [Using] Me.MessageDeliveryLock.Enter
                [Using] New ServiceEnvironment(Me.rootActivity)
                    SyncLock Me.qService.SyncRoot
                        Dim comparable As IComparable
                        For Each comparable In Me.qService.QueueNames
                            Try 
                                If Me.qService.GetWorkflowQueue(comparable).Enabled Then
                                    Dim messages As Queue = Me.qService.GetQueue(comparable).Messages
                                    Dim asynchronousListeners As List([Of] ActivityExecutorDelegateInfo([Of] QueueEventArgs)) = Me.qService.GetQueue(comparable).AsynchronousListeners
                                    Dim list3 As New List([Of] String)
                                    Dim info As ActivityExecutorDelegateInfo([Of] QueueEventArgs)
                                    For Each info In asynchronousListeners
                                        Dim item As String = If((info.SubscribedActivityQualifiedName Is Nothing), info.ActivityQualifiedName, info.SubscribedActivityQualifiedName)
                                        list3.Add(item)
                                    Next
                                    list.Add(New WorkflowQueueInfo(comparable, messages, list3.AsReadOnly))
                                End If
                                [Continue] For
                            Catch exception1 As InvalidOperationException
                                [Continue] For
                            End Try
                        Next
                    End SyncLock
                End [Using]
            End [Using]
            Return list.AsReadOnly
        End Function

        Private Function HasNonEmptyWorkBatch() As Boolean
            Dim batch As WorkBatch
            For Each batch In Me.ResourceManager.BatchCollection.Values
                If (batch.Count > 0) Then
                    Return True
                End If
            Next
            Return False
        End Function

        Friend Sub Initialize(ByVal rootActivity As Activity, ByVal runtime As WorkflowRuntime, ByVal previousWorkflowExecutor As WorkflowExecutor)
            Me._workflowInstance = previousWorkflowExecutor.WorkflowInstance
            Me.ReloadHelper(rootActivity)
            Me.IsInstanceValid = True
            Me._runtime = runtime
            Me._runtime.WorkflowExecutorCreated(Me, True)
            Me.TimerQueue.Executor = Me
            Me.TimerQueue.ResumeDelivery
            Me._executorLock = previousWorkflowExecutor._executorLock
            Me._msgDeliveryLock = previousWorkflowExecutor._msgDeliveryLock
            Me._schedulerLock = previousWorkflowExecutor._schedulerLock
            ScheduleWork.Executor = Me
        End Sub

        Friend Sub Initialize(ByVal rootActivity As Activity, ByVal invokerExec As WorkflowExecutor, ByVal invokeActivityID As String, ByVal instanceId As Guid, ByVal namedArguments As IDictionary([Of] String, Object), ByVal workflowInstance As WorkflowInstance)
            Me.rootActivity = rootActivity
            Me.InstanceId = instanceId
            Me.rootActivity.SetValue(WorkflowExecutor.ContextIdProperty, 0)
            Me.rootActivity.SetValue(WorkflowExecutor.WorkflowInstanceIdProperty, instanceId)
            Me.WorkflowStatus = WorkflowStatus.Created
            Me.rootActivity.SetValue(Activity.ActivityExecutionContextInfoProperty, New ActivityExecutionContextInfo(Me.rootActivity.QualifiedName, Me.GetNewContextId, instanceId, -1))
            Me.rootActivity.SetValue(Activity.ActivityContextGuidProperty, instanceId)
            Me.rootActivity.SetValue(WorkflowExecutor.IsIdleProperty, True)
            Me.isInstanceIdle = True
            Me.rootActivity.SetValue(WorkflowExecutor.WorkflowExecutorProperty, Me)
            Me.RefreshWorkflowDefinition
            Dim workflowDefinition As Activity = Me.WorkflowDefinition
            If (workflowDefinition Is Nothing) Then
                Throw New InvalidOperationException("workflowDefinition")
            End If
            DirectCast(Me.rootActivity, IDependencyObjectAccessor).InitializeActivatingInstanceForRuntime(Nothing, Me)
            Me.rootActivity.FixUpMetaProperties(workflowDefinition)
            Me._runtime = workflowInstance.WorkflowRuntime
            If (Not invokerExec Is Nothing) Then
                Dim list As New List([Of] String)
                Dim state As TrackingCallingState = DirectCast(invokerExec.rootActivity.GetValue(WorkflowExecutor.TrackingCallingStateProperty), TrackingCallingState)
                If ((Not state Is Nothing) AndAlso (Not state.CallerActivityPathProxy Is Nothing)) Then
                    Dim str As String
                    For Each str In state.CallerActivityPathProxy
                        list.Add(str)
                    Next
                End If
                list.Add(invokeActivityID)
                Dim state2 As New TrackingCallingState { _
                    .CallerActivityPathProxy = list, _
                    .CallerWorkflowInstanceId = invokerExec.InstanceId, _
                    .CallerContextGuid = DirectCast(ContextActivityUtils.ContextActivity(invokerExec.CurrentActivity).GetValue(Activity.ActivityExecutionContextInfoProperty), ActivityExecutionContextInfo).ContextGuid _
                }
                If (invokerExec.CurrentActivity.Parent Is Nothing) Then
                    state2.CallerParentContextGuid = state2.CallerContextGuid
                Else
                    state2.CallerParentContextGuid = DirectCast(ContextActivityUtils.ContextActivity(invokerExec.CurrentActivity.Parent).GetValue(Activity.ActivityExecutionContextInfoProperty), ActivityExecutionContextInfo).ContextGuid
                End If
                Me.rootActivity.SetValue(WorkflowExecutor.TrackingCallingStateProperty, state2)
            End If
            Me._setInArgsOnCompanion(namedArguments)
            Me.schedulingContext = New Scheduler(Me, True)
            Me._schedulerLock = LockFactory.CreateWorkflowSchedulerLock(Me.InstanceId)
            Me.qService = New WorkflowQueuingService(Me)
            Me._workflowInstance = workflowInstance
            Me.TimerQueue = New TimerEventSubscriptionCollection(Me)
            [Using] New ServiceEnvironment(Me.rootActivity)
                [Using] Me.SetCurrentActivity(Me.rootActivity)
                    Me.RegisterDynamicActivity(Me.rootActivity, False)
                End [Using]
            End [Using]
        End Sub

        Friend Function IsActivityInAtomicContext(ByVal activity As Activity, <Out> ByRef atomicActivity As Activity) As Boolean
            atomicActivity = Nothing
            Do While (Not activity Is Nothing)
                If (activity Is Me.currentAtomicActivity) Then
                    atomicActivity = activity
                    Return True
                End If
                activity = activity.Parent
            Loop
            Return False
        End Function

        Friend Shared Function IsIrrecoverableException(ByVal e As Exception) As Boolean
            Return (((TypeOf e Is OutOfMemoryException OrElse TypeOf e Is ExecutionEngineException) OrElse (TypeOf e Is StackOverflowException OrElse TypeOf e Is ThreadInterruptedException)) OrElse TypeOf e Is ThreadAbortException)
        End Function

        Friend Sub OnAfterDynamicChange(ByVal updateSucceeded As Boolean, ByVal changes As IList([Of] WorkflowChangeAction))
            If updateSucceeded Then
                Me.RefreshWorkflowDefinition
                Me.FireDynamicUpdateCommit(changes)
                Me.FireWorkflowExecutionEvent(Me, WorkflowEventInternal.Changed)
            Else
                Me.FireDynamicUpdateRollback(changes)
            End If
            WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 0, "Workflow Runtime: WorkflowExecutor: Done updating a schedule in instance {0}", New Object() { Me.InstanceIdString })
        End Sub

        Friend Function OnBeforeDynamicChange(ByVal changes As IList([Of] WorkflowChangeAction)) As Boolean
            WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 0, "Workflow Runtime: WorkflowExecutor: Got a dynamic update request for instance {0}", New Object() { Me.InstanceIdString })
            If Not Me.IsInstanceValid Then
                Throw New InvalidOperationException(ExecutionStringManager.WorkflowNotValid)
            End If
            WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 0, "Workflow Runtime: WorkflowExecutor: Found a match for the schedule in updating instance {0}", New Object() { Me.InstanceIdString })
            Me.FireDynamicUpdateBegin(changes)
            Return True
        End Function

        Private Function PerformUnloading(ByVal handleExceptions As Boolean) As Boolean
            WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 0, "Workflow Runtime: WorkflowExecutor: Unloading instance {0}", New Object() { Me.InstanceIdString })
            Me.FireWorkflowExecutionEvent(Me, WorkflowEventInternal.Unloading)
            [Using] Me._msgDeliveryLock.Enter
                Dim flag As Boolean
                Me.TimerQueue.SuspendDelivery
                If handleExceptions Then
                    WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 0, (Me.InstanceId & ": Calling PerformUnloading(false): InstanceId {0}, hc: {1}"), New Object() { Me.InstanceIdString, Me.GetHashCode })
                    flag = Me.ProtectedPersist(True)
                    WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 0, (Me.InstanceId & ": Returning from ProtectedPersist: InstanceId {0}, hc: {1}, ret={2}"), New Object() { Me.InstanceIdString, Me.GetHashCode, flag })
                Else
                    WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 0, (Me.InstanceId & ": Calling Persist"))
                    Me.Persist(Me.rootActivity, True, False)
                    flag = True
                    WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 0, (Me.InstanceId & ": Returning from Persist: InstanceId {0}, hc: {1}, IsInstanceValid={2}"), New Object() { Me.InstanceIdString, Me.GetHashCode, Me.IsInstanceValid })
                End If
                If flag Then
                    Me.IsInstanceValid = False
                    Me.FireEventAfterSchedulerLockDrop(WorkflowEventInternal.Unloaded)
                    Return True
                End If
                Return False
            End [Using]
        End Function

        Friend Sub Persist(ByVal dynamicActivity As Activity, ByVal unlock As Boolean, ByVal needsCompensation As Boolean)
            Dim currentActivity As Activity = If((Me.CurrentActivity Is Nothing), dynamicActivity, Me.CurrentActivity)
            Dim workflowStatus As WorkflowStatus = Me.WorkflowStatus
            [Using] New ServiceEnvironment(currentActivity)
                Try 
                    [Using] Me.MessageDeliveryLock.Enter
                        Me.ProcessQueuedEvents
                        If Me.ResourceManager.IsBatchDirty Then
                            Me.stateChangedSincePersistence = True
                        ElseIf (Not Me.stateChangedSincePersistence AndAlso Not unlock) Then
                            WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 0, "Workflow Runtime: WorkflowExecutor: NOT Persisting Instance '{0}' since the batch is NOT dirty and the instance state is NOT dirty", New Object() { Me.InstanceIdString })
                            Return
                        End If
                        Me.PrePersist
                        If (WorkflowStatus.Completed = Me.WorkflowStatus) Then
                            Me.qService.MoveAllMessagesToPendingQueue
                        End If
                        Dim workflowPersistenceService As WorkflowPersistenceService = Me.WorkflowRuntime.WorkflowPersistenceService
                        currentActivity.SetValue(WorkflowExecutor.TransientBatchProperty, Me._resourceManager.BatchCollection.GetTransientBatch)
                        Dim flag As Boolean = False
                        If (Not workflowPersistenceService Is Nothing) Then
                            Dim activity2 As Activity
                            For Each activity2 In Me.completedContextActivities.Values
                                activity2.SetValue(WorkflowExecutor.WorkflowInstanceIdProperty, Me.InstanceId)
                                If Not flag Then
                                    Me.FireWorkflowExecutionEvent(Me, WorkflowEventInternal.Persisting)
                                    flag = True
                                End If
                                workflowPersistenceService.SaveCompletedContextActivity(activity2)
                                activity2.Dispose
                            Next
                            If Me.stateChangedSincePersistence Then
                                If Not flag Then
                                    Me.FireWorkflowExecutionEvent(Me, WorkflowEventInternal.Persisting)
                                    flag = True
                                End If
                                WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 0, "Workflow Runtime: WorkflowExecutor: Calling SaveWorkflowInstanceState for instance {0} hc {1}", New Object() { Me.InstanceIdString, Me.GetHashCode })
                                workflowPersistenceService.SaveWorkflowInstanceState(Me.rootActivity, unlock)
                            ElseIf unlock Then
                                workflowPersistenceService.UnlockWorkflowInstanceState(Me.rootActivity)
                            End If
                        End If
                        If unlock Then
                            Me.DisposeRootActivity(False)
                        End If
                        If (((Not Me.currentAtomicActivity Is Nothing) OrElse Me.ResourceManager.IsBatchDirty) OrElse (unlock AndAlso Me.HasNonEmptyWorkBatch)) Then
                            WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 0, "Workflow Runtime: WorkflowExecutor: Calling CommitTransaction for instance {0} hc {1}", New Object() { Me.InstanceIdString, Me.GetHashCode })
                            Me.CommitTransaction(currentActivity)
                        End If
                        If flag Then
                            Me.FireEventAfterSchedulerLockDrop(WorkflowEventInternal.Persisted)
                        End If
                        Me.stateChangedSincePersistence = False
                        Me.PostPersist
                        If (WorkflowStatus.Completed = Me.WorkflowStatus) Then
                            Me.FireEventAfterSchedulerLockDrop(WorkflowEventInternal.Completed)
                            Me.IsInstanceValid = False
                        End If
                    End [Using]
                Catch exception As PersistenceException
                    Me.Rollback(workflowStatus)
                    WorkflowTrace.Runtime.TraceEvent(TraceEventType.Error, 0, "Workflow Runtime: WorkflowExecutor: Persist attempt on instance '{0}' threw an exception '{1}' at {2}", New Object() { Me.InstanceIdString, exception.Message, exception.StackTrace })
                    Throw
                Catch exception2 As Exception
                    If WorkflowExecutor.IsIrrecoverableException(exception2) Then
                        Throw
                    End If
                    Me.Rollback(workflowStatus)
                    WorkflowTrace.Runtime.TraceEvent(TraceEventType.Error, 0, "Workflow Runtime: WorkflowExecutor: Persist attempt on instance '{0}' threw an exception '{1}' at {2}", New Object() { Me.InstanceIdString, exception2.Message, exception2.StackTrace })
                    Throw New PersistenceException(exception2.Message, exception2)
                Finally
                    currentActivity.SetValue(WorkflowExecutor.TransientBatchProperty, Nothing)
                End Try
            End [Using]
        End Sub

        Private Sub PostPersist()
            Me.qService.PostPersist(True)
            If (Not Me.Scheduler Is Nothing) Then
                Me.Scheduler.PostPersist
            End If
            Me.completedContextActivities.Clear
        End Sub

        Private Sub PrePersist()
            Dim workflowStatus As WorkflowStatus = Me.WorkflowStatus
            If ((ActivityExecutionStatus.Closed = Me.rootActivity.ExecutionStatus) AndAlso (WorkflowStatus.Terminated <> workflowStatus)) Then
                Me.FireWorkflowExecutionEvent(Me, WorkflowEventInternal.Completing)
                Me.WorkflowStatus = WorkflowStatus.Completed
            End If
            Select Case Me.WorkflowStatus
                Case WorkflowStatus.Running
                    Me.rootActivity.SetValue(WorkflowExecutor.IsBlockedProperty, Me.Scheduler.IsStalledNow)
                    Exit Select
                Case WorkflowStatus.Completed, WorkflowStatus.Suspended, WorkflowStatus.Terminated, WorkflowStatus.Created
                    Me.rootActivity.SetValue(WorkflowExecutor.IsBlockedProperty, False)
                    Exit Select
            End Select
            Me.qService.PrePersist
        End Sub

        Friend Sub ProcessQueuedEvents()
            [Using] Me.MessageDeliveryLock.Enter
                Me.qService.ProcessesQueuedAsynchronousEvents
            End [Using]
        End Sub

        Private Function ProtectedPersist(ByVal unlock As Boolean) As Boolean
            Try 
                Me.Persist(Me.rootActivity, unlock, False)
            Catch exception As Exception
                If WorkflowExecutor.IsIrrecoverableException(exception) Then
                    Throw
                End If
                If ((Me.WorkflowStatus <> WorkflowStatus.Suspended) AndAlso Me.IsInstanceValid) Then
                    Dim currentActivity As Activity = Me.FindExecutorToHandleException
                    Me.Scheduler.CanRun = True
                    Me.ExceptionOccured(exception, currentActivity, Nothing)
                ElseIf Me.TerminateOnIdle(WorkflowExecutor.GetNestedExceptionMessage(exception)) Then
                    Me.stateChangedSincePersistence = True
                    Me.WorkflowStatus = WorkflowStatus.Terminated
                End If
                Return False
            End Try
            Return True
        End Function

        Private Sub RefreshWorkflowDefinition()
            Me._workflowDefinition = DirectCast(Me.rootActivity.GetValue(Activity.WorkflowDefinitionProperty), Activity)
            If (WorkflowDefinitionLock.GetWorkflowDefinitionLockObject(Me._workflowDefinition) Is Nothing) Then
                WorkflowDefinitionLock.SetWorkflowDefinitionLockObject(Me._workflowDefinition, New Object)
            End If
        End Sub

        Friend Sub RegisterDynamicActivity(ByVal dynamicActivity As Activity, ByVal load As Boolean)
            Dim key As Integer = ContextActivityUtils.ContextId(dynamicActivity)
            Me.subStateMap.Add(key, dynamicActivity)
            WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 0, "Adding context {0}:{1}", New Object() { key, (dynamicActivity.QualifiedName & If(load, " for load", "")) })
            dynamicActivity.OnActivityExecutionContextLoad(Me)
        End Sub

        Friend Sub Registered(ByVal isActivation As Boolean)
            [Using] New ScheduleWork(Me)
                Me.Scheduler.ResumeIfRunnable
            End [Using]
            If isActivation Then
                Me.FireWorkflowExecutionEvent(Me, WorkflowEventInternal.Created)
            Else
                Me.FireWorkflowExecutionEvent(Me, WorkflowEventInternal.Loaded)
            End If
        End Sub

        Friend Sub RegisterWithRuntime(ByVal workflowRuntime As WorkflowRuntime)
            Me._isInstanceValid = True
            Me._runtime = workflowRuntime
            [Using] New ServiceEnvironment(Me.rootActivity)
                [Using] Me.SetCurrentActivity(Me.rootActivity)
                    [Using] context As ActivityExecutionContext = New ActivityExecutionContext(Me.rootActivity, True)
                        context.InitializeActivity(Me.rootActivity)
                    End [Using]
                End [Using]
                Me._runtime.WorkflowExecutorCreated(Me, False)
                Me.FireWorkflowExecutionEvent(Me, WorkflowEventInternal.Creating)
            End [Using]
        End Sub

        Friend Sub Reload(ByVal rootActivity As Activity, ByVal workflowInstance As WorkflowInstance)
            Me._workflowInstance = workflowInstance
            Me.ReloadHelper(rootActivity)
        End Sub

        Private Sub ReloadHelper(ByVal rootActivity As Activity)
            Me.rootActivity = rootActivity
            Me.InstanceId = DirectCast(rootActivity.GetValue(WorkflowExecutor.WorkflowInstanceIdProperty), Guid)
            Me.rootActivity.SetValue(WorkflowExecutor.WorkflowExecutorProperty, Me)
            Me._schedulerLock = LockFactory.CreateWorkflowSchedulerLock(Me.InstanceId)
            Me.schedulingContext = New Scheduler(Me, False)
            Me.qService = New WorkflowQueuingService(Me)
            WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 0, "Workflow Runtime: WorkflowExecutor: Loading instance {0}", New Object() { Me.InstanceIdString })
            [Using] New ServiceEnvironment(Me.rootActivity)
                Select Case Me.WorkflowStatus
                    Case WorkflowStatus.Completed, WorkflowStatus.Terminated
                        WorkflowTrace.Runtime.TraceEvent(TraceEventType.Error, 0, "Workflow Runtime: WorkflowExecutor: attempt to load a completed/terminated instance: {0}", New Object() { Me.InstanceIdString })
                        Throw New InvalidOperationException(ExecutionStringManager.InvalidAttemptToLoad)
                End Select
                Me._resourceManager = New VolatileResourceManager
                Me._runtime = Me._workflowInstance.WorkflowRuntime
                Dim queue As New Queue([Of] Activity)
                queue.Enqueue(Me.rootActivity)
                Do While (queue.Count > 0)
                    Dim dynamicActivity As Activity = queue.Dequeue
                    DirectCast(dynamicActivity, IDependencyObjectAccessor).InitializeInstanceForRuntime(Me)
                    Me.RegisterDynamicActivity(dynamicActivity, True)
                    Dim list As IList([Of] Activity) = DirectCast(dynamicActivity.GetValue(Activity.ActiveExecutionContextsProperty), IList([Of] Activity))
                    If (Not list Is Nothing) Then
                        Dim activity2 As Activity
                        For Each activity2 In list
                            queue.Enqueue(activity2)
                        Next
                    End If
                Loop
            End [Using]
            Me.isInstanceIdle = CBool(Me.rootActivity.GetValue(WorkflowExecutor.IsIdleProperty))
            Me.RefreshWorkflowDefinition
        End Sub

        Friend Sub RequestHostingService()
            Me.WorkflowRuntime.SchedulerService.Schedule(New WaitCallback(AddressOf Me.RunSome), Me.InstanceId)
        End Sub

        Friend Sub ReRegisterWithRuntime(ByVal workflowRuntime As WorkflowRuntime)
            [Using] New SchedulerLockGuard(Me._schedulerLock, Me)
                Me._isInstanceValid = True
                Me._runtime = workflowRuntime
                [Using] New ServiceEnvironment(Me.rootActivity)
                    Me._runtime.WorkflowExecutorCreated(Me, True)
                    Me.TimerQueue.Executor = Me
                    Me.TimerQueue.ResumeDelivery
                    If (Me.WorkflowStatus = WorkflowStatus.Running) Then
                        Me.Scheduler.CanRun = True
                    End If
                    Me.FireWorkflowExecutionEvent(Me, WorkflowEventInternal.Loading)
                End [Using]
            End [Using]
        End Sub

        Friend Sub [Resume]()
            WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 0, "Workflow Runtime: WorkflowExecutor: Got a resume request for instance {0}", New Object() { Me.InstanceIdString })
            Try 
                If Not Me.IsInstanceValid Then
                    Throw New InvalidOperationException(ExecutionStringManager.WorkflowNotValid)
                End If
                [Using] New ScheduleWork(Me)
                    [Using] Me._executorLock.Enter
                        If Not Me.IsInstanceValid Then
                            Throw New InvalidOperationException(ExecutionStringManager.WorkflowNotValid)
                        End If
                        If (Me.WorkflowStatus = WorkflowStatus.Suspended) Then
                            [Using] New SchedulerLockGuard(Me._schedulerLock, Me)
                                [Using] New ServiceEnvironment(Me.rootActivity)
                                    Me.ResumeOnIdle(True)
                                End [Using]
                            End [Using]
                        End If
                    End [Using]
                End [Using]
            Catch exception As Exception
                WorkflowTrace.Runtime.TraceEvent(TraceEventType.Error, 0, "Workflow Runtime: WorkflowExecutor: Resume attempt on instance '{0}' threw an exception '{1}' at {2}", New Object() { Me.InstanceIdString, exception.Message, exception.StackTrace })
                Throw
            End Try
        End Sub

        Friend Function ResumeOnIdle(ByVal outsideThread As Boolean) As Boolean
            If Not Me.IsInstanceValid Then
                Return False
            End If
            If ((Me.WorkflowStatus <> WorkflowStatus.Suspended) AndAlso Not Me.Scheduler.CanRun) Then
                Return False
            End If
            Me.FireWorkflowExecutionEvent(Me, WorkflowEventInternal.Resuming)
            WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 0, "Workflow Runtime: WorkflowExecutor: Resuming instance {0}", New Object() { Me.InstanceIdString })
            Me.stateChangedSincePersistence = True
            Me.WorkflowStatus = WorkflowStatus.Running
            Me.rootActivity.SetValue(WorkflowExecutor.SuspendOrTerminateInfoProperty, String.Empty)
            Me.FireEventAfterSchedulerLockDrop(WorkflowEventInternal.Resumed, Me.ThrownException)
            [Using] Me._msgDeliveryLock.Enter
                Me.TimerQueue.ResumeDelivery
            End [Using]
            If outsideThread Then
                Me.Scheduler.Resume
            Else
                Me.Scheduler.CanRun = True
            End If
            Return True
        End Function

        Private Sub Rollback(ByVal oldStatus As WorkflowStatus)
            Me.WorkflowStatus = oldStatus
            If (Not Me.Scheduler Is Nothing) Then
                Me.Scheduler.Rollback
            End If
        End Sub

        Private Sub RollbackTransaction(ByVal exp As Exception, ByVal activityContext As Activity)
            If (activityContext Is Me.currentAtomicActivity) Then
                Dim transactionalProperties As TransactionalProperties = DirectCast(activityContext.GetValue(WorkflowExecutor.TransactionalPropertiesProperty), TransactionalProperties)
                If (transactionalProperties.TransactionState <> TransactionProcessState.AbortProcessed) Then
                    transactionalProperties.TransactionState = TransactionProcessState.AbortProcessed
                End If
                Try 
                    Me.DisposeTransactionScope(transactionalProperties)
                    Dim transaction As Transaction = transactionalProperties.Transaction
                    If (TransactionStatus.Aborted <> transaction.TransactionInformation.Status) Then
                        transaction.Rollback
                    End If
                    WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 0, String.Concat(New Object() { "Workflow Runtime: WorkflowExecutor: instanceId: ", Me.InstanceIdString, " .Aborted enlistable transaction ", transaction.GetHashCode }))
                Finally
                    transactionalProperties.LocalQueuingService.Complete(False)
                    Me.DisposeTransaction(Me.currentAtomicActivity)
                End Try
            End If
        End Sub

        Private Sub RunScheduler()
            Try 
                Me.Scheduler.Run
            Finally
                Me.IsIdle = True
            End Try
            If Not Me.IsInstanceValid Then
                Return
            End If
            If Me.WorkflowStateRollbackService.IsInstanceStateRevertRequested Then
                [Using] Me.MessageDeliveryLock.Enter
                    Me.WorkflowStateRollbackService.RevertToCheckpointState
                    Return
                End [Using]
            End If
            If Me.Scheduler.IsStalledNow Then
                [Using] Me.MessageDeliveryLock.Enter
                    If (Me.rootActivity.ExecutionStatus <> ActivityExecutionStatus.Closed) Then
                        Me.ProcessQueuedEvents
                        If Me.Scheduler.IsStalledNow Then
                            WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 0, "Workflow Runtime: WorkflowExecutor: workflow instance '{0}' has no work.", New Object() { Me.InstanceIdString })
                            Me.FireWorkflowExecutionEvent(Me, WorkflowEventInternal.SchedulerEmpty)
                            Me.FireEventAfterSchedulerLockDrop(WorkflowEventInternal.Idle)
                            Dim workflowPersistenceService As WorkflowPersistenceService = Me.WorkflowRuntime.WorkflowPersistenceService
                            If ((Not workflowPersistenceService Is Nothing) AndAlso workflowPersistenceService.UnloadOnIdle(Me.rootActivity)) Then
                                If Not Me.IsInstanceValid Then
                                    Return
                                End If
                                If (Me.IsUnloadableNow AndAlso Not TypeOf Me.ThrownException Is PersistenceException) Then
                                    Me.PerformUnloading(True)
                                    WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 0, "WorkflowExecutor: unloaded workflow instance '{0}'.  IsInstanceValid={1}", New Object() { Me.InstanceIdString, Me.IsInstanceValid })
                                End If
                            ElseIf (Me.ResourceManager.IsBatchDirty AndAlso (Me.currentAtomicActivity Is Nothing)) Then
                                WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 0, "Workflow Runtime: WorkflowExecutor: workflow instance '{0}' has no work and the batch is dirty. Persisting state and commiting batch.", New Object() { Me.InstanceIdString })
                                Me.Persist(Me.rootActivity, False, False)
                            End If
                        End If
                    End If
                    goto Label_01E1
                End [Using]
            End If
            If CBool(Me.rootActivity.GetValue(WorkflowExecutor.IsSuspensionRequestedProperty)) Then
                Me.SuspendOnIdle(Me.AdditionalInformation)
                Me.rootActivity.SetValue(WorkflowExecutor.IsSuspensionRequestedProperty, False)
            End If
        Label_01E1:
            If (Not Me.currentAtomicActivity Is Nothing) Then
                Dim transactionalProperties As TransactionalProperties = DirectCast(Me.currentAtomicActivity.GetValue(WorkflowExecutor.TransactionalPropertiesProperty), TransactionalProperties)
                Me.DisposeTransactionScope(transactionalProperties)
            End If
        End Sub

        Friend Sub RunSome(ByVal ignored As Object)
            [Using] New ScheduleWork(Me)
                [Using] New WorkflowTraceTransfer(Me.InstanceId)
                    [Using] New SchedulerLockGuard(Me._schedulerLock, Me)
                        [Using] New ServiceEnvironment(Me.rootActivity)
                            If (Me.IsInstanceValid AndAlso (((Me.rootActivity.ExecutionStatus <> ActivityExecutionStatus.Closed) AndAlso (WorkflowStatus.Completed <> Me.WorkflowStatus)) AndAlso (WorkflowStatus.Terminated <> Me.WorkflowStatus))) Then
                                Dim flag As Boolean = False
                                [Using] scope As TransactionScope = New TransactionScope(TransactionScopeOption.Suppress)
                                    Try 
                                        Me.FireWorkflowExecutionEvent(Me, WorkflowEventInternal.Executing)
                                        Me.RunScheduler
                                    Catch exception As Exception
                                        If WorkflowExecutor.IsIrrecoverableException(exception) Then
                                            flag = True
                                            Throw
                                        End If
                                        WorkflowTrace.Runtime.TraceEvent(TraceEventType.Error, 0, "Workflow Runtime: WorkflowExecutor: Fatal exception thrown in the scheduler. Terminating the workflow instance '{0}'. Exception:{1}" & ChrW(10) & "{2}", New Object() { Me.InstanceIdString, exception.Message, exception.StackTrace })
                                        Me.TerminateOnIdle(WorkflowExecutor.GetNestedExceptionMessage(exception))
                                        Me.ThrownException = exception
                                    Finally
                                        If Not flag Then
                                            Me.FireWorkflowExecutionEvent(Me, WorkflowEventInternal.NotExecuting)
                                        End If
                                    End Try
                                    scope.Complete
                                End [Using]
                            End If
                        End [Using]
                    End [Using]
                End [Using]
            End [Using]
        End Sub

        Private Sub ScheduleDelayedItems(ByVal atomicActivity As Activity)
            Dim itemsToBeScheduledAtCompletion As List([Of] SchedulableItem) = Nothing
            Dim properties As TransactionalProperties = DirectCast(atomicActivity.GetValue(WorkflowExecutor.TransactionalPropertiesProperty), TransactionalProperties)
            If (Not properties Is Nothing) Then
                SyncLock properties
                    itemsToBeScheduledAtCompletion = properties.ItemsToBeScheduledAtCompletion
                    If (Not itemsToBeScheduledAtCompletion Is Nothing) Then
                        WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 0, String.Concat(New Object() { "Workflow Runtime: WorkflowExecutor: instanceId: ", Me.InstanceIdString, " .Scheduling delayed ", itemsToBeScheduledAtCompletion.Count, " number of items" }))
                        Dim item As SchedulableItem
                        For Each item In itemsToBeScheduledAtCompletion
                            Me.Scheduler.ScheduleItem(item, False, True)
                        Next
                        itemsToBeScheduledAtCompletion.Clear
                        properties.ItemsToBeScheduledAtCompletion = Nothing
                    End If
                End SyncLock
            End If
        End Sub

        Friend Sub ScheduleForWork()
            Me.IsIdle = False
            If Me.IsInstanceValid Then
                Me.FireWorkflowExecutionEvent(Me, WorkflowEventInternal.Runnable)
            End If
            ScheduleWork.NeedsService = True
        End Sub

        Public Function SetCurrentActivity(ByVal activity As Activity) As IDisposable
            If Not ServiceEnvironment.IsInServiceThread(Me.InstanceId) Then
                Throw New InvalidOperationException(ExecutionStringManager.MustUseRuntimeThread)
            End If
            Dim currentActivity As Activity = Me.CurrentActivity
            Me.CurrentActivity = activity
            Return New ResetCurrentActivity(Me, currentActivity)
        End Function

        Friend Sub Start()
            [Using] New ScheduleWork(Me)
                [Using] Me.ExecutorLock.Enter
                    If (Me.WorkflowStatus <> WorkflowStatus.Created) Then
                        Throw New InvalidOperationException(String.Format(CultureInfo.CurrentCulture, ExecutionStringManager.CannotStartInstanceTwice, New Object() { Me.InstanceId }))
                    End If
                    Me.WorkflowStatus = WorkflowStatus.Running
                    [Using] New ServiceEnvironment(Me.rootActivity)
                        Me.FireWorkflowExecutionEvent(Me, WorkflowEventInternal.Starting)
                        Try 
                            [Using] context As ActivityExecutionContext = New ActivityExecutionContext(Me.rootActivity, True)
                                Me.schedulingContext.CanRun = True
                                [Using] New SchedulerLockGuard(Me._schedulerLock, Me)
                                    context.ExecuteActivity(Me.rootActivity)
                                End [Using]
                            End [Using]
                        Catch exception As Exception
                            Me.Terminate(exception.Message)
                            Throw
                        End Try
                        Me.FireWorkflowExecutionEvent(Me, WorkflowEventInternal.Started)
                    End [Using]
                End [Using]
            End [Using]
        End Sub

        Friend Function Suspend(ByVal [error] As String) As Boolean
            Dim flag As Boolean
            WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 0, "Workflow Runtime: WorkflowExecutor: Got a suspend request for instance {0}", New Object() { Me.InstanceIdString })
            Try 
                If Not Me.IsInstanceValid Then
                    Throw New InvalidOperationException(ExecutionStringManager.WorkflowNotValid)
                End If
                [Using] Me._executorLock.Enter
                    If Not Me.IsInstanceValid Then
                        Throw New InvalidOperationException(ExecutionStringManager.WorkflowNotValid)
                    End If
                    Me.Scheduler.CanRun = False
                    [Using] New SchedulerLockGuard(Me._schedulerLock, Me)
                        [Using] New ServiceEnvironment(Me.rootActivity)
                            If Not Me.IsInstanceValid Then
                                Throw New InvalidOperationException(ExecutionStringManager.WorkflowNotValid)
                            End If
                            flag = Me.SuspendOnIdle([error])
                        End [Using]
                    End [Using]
                End [Using]
            Catch exception As Exception
                WorkflowTrace.Runtime.TraceEvent(TraceEventType.Error, 0, "Workflow Runtime: WorkflowExecutor: Suspend attempt on instance '{0}' threw an exception '{1}' at {2}", New Object() { Me.InstanceIdString, exception.Message, exception.StackTrace })
                Throw
            End Try
            Return flag
        End Function

        Friend Function SuspendOnIdle(ByVal [error] As String) As Boolean
            If Me.IsInstanceValid Then
                If (Not Me.currentAtomicActivity Is Nothing) Then
                    Me.Scheduler.CanRun = True
                    Throw New ExecutorLocksHeldException(Me.atomicActivityEvent)
                End If
                Select Case Me.WorkflowStatus
                    Case WorkflowStatus.Suspended, WorkflowStatus.Created
                        Return False
                End Select
                Me.FireWorkflowSuspending([error])
                Me.Scheduler.CanRun = False
                Select Case Me.rootActivity.ExecutionStatus
                    Case ActivityExecutionStatus.Initialized, ActivityExecutionStatus.Executing, ActivityExecutionStatus.Canceling, ActivityExecutionStatus.Compensating, ActivityExecutionStatus.Faulting
                        WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 0, "Workflow Runtime: WorkflowExecutor: Suspending instance {0}", New Object() { Me.InstanceIdString })
                        Me.stateChangedSincePersistence = True
                        Me.WorkflowStatus = WorkflowStatus.Suspended
                        Me.rootActivity.SetValue(WorkflowExecutor.SuspendOrTerminateInfoProperty, [error])
                        Me.FireEventAfterSchedulerLockDrop(WorkflowEventInternal.Suspended, [error])
                        Return True
                    Case ActivityExecutionStatus.Closed
                        Return False
                End Select
            End If
            Return False
        End Function

        Private Function System.IServiceProvider.GetService(ByVal serviceType As Type) As Object Implements IServiceProvider.GetService
            Return DirectCast(Me, IWorkflowCoreRuntime).GetService(Me.rootActivity, serviceType)
        End Function

        Private Sub System.Workflow.ComponentModel.IWorkflowCoreRuntime.ActivityStatusChanged(ByVal activity As Activity, ByVal transacted As Boolean, ByVal committed As Boolean) Implements IWorkflowCoreRuntime.ActivityStatusChanged
            If Not ServiceEnvironment.IsInServiceThread(Me.InstanceId) Then
                Throw New InvalidOperationException(ExecutionStringManager.MustUseRuntimeThread)
            End If
            If Not committed Then
                If (activity.ExecutionStatus = ActivityExecutionStatus.Executing) Then
                    If ((If((Not TransactedContextFilter.GetTransactionOptions(activity) Is Nothing), 1, 0) <> 0) AndAlso (Me.WorkflowRuntime.WorkflowPersistenceService Is Nothing)) Then
                        Dim message As String = String.Format(CultureInfo.CurrentCulture, ExecutionStringManager.MissingPersistenceService, New Object() { Me.InstanceId })
                        WorkflowTrace.Runtime.TraceEvent(TraceEventType.Error, 0, message)
                        Throw New InvalidOperationException(message)
                    End If
                ElseIf (activity.ExecutionStatus = ActivityExecutionStatus.Closed) Then
                    Me.ScheduleDelayedItems(activity)
                ElseIf (((activity.ExecutionStatus = ActivityExecutionStatus.Canceling) OrElse (activity.ExecutionStatus = ActivityExecutionStatus.Faulting)) AndAlso (Not TransactedContextFilter.GetTransactionOptions(activity) Is Nothing)) Then
                    Me.BatchCollection.RollbackBatch(activity)
                End If
            End If
            If Not committed Then
                Me.FireActivityStatusChange(Me, activity)
            End If
            If ((activity.ExecutionStatus = ActivityExecutionStatus.Closed) AndAlso (Not TypeOf activity Is ICompensatableActivity OrElse (TypeOf activity Is ICompensatableActivity AndAlso activity.CanUninitializeNow))) Then
                CorrelationTokenCollection.UninitializeCorrelationTokens(activity)
            End If
        End Sub

        Private Sub System.Workflow.ComponentModel.IWorkflowCoreRuntime.CheckpointInstanceState(ByVal currentActivity As Activity) Implements IWorkflowCoreRuntime.CheckpointInstanceState
            If Not ServiceEnvironment.IsInServiceThread(Me.InstanceId) Then
                Throw New InvalidOperationException(ExecutionStringManager.MustUseRuntimeThread)
            End If
            [Using] Me.MessageDeliveryLock.Enter
                Me.WorkflowStateRollbackService.CheckpointInstanceState
            End [Using]
            Me.CreateTransaction(currentActivity)
        End Sub

        Private Sub System.Workflow.ComponentModel.IWorkflowCoreRuntime.DisposeCheckpointState() Implements IWorkflowCoreRuntime.DisposeCheckpointState
            If Not ServiceEnvironment.IsInServiceThread(Me.InstanceId) Then
                Throw New InvalidOperationException(ExecutionStringManager.MustUseRuntimeThread)
            End If
            Me.WorkflowStateRollbackService.DisposeCheckpointState
        End Sub

        Private Function System.Workflow.ComponentModel.IWorkflowCoreRuntime.GetContextActivityForId(ByVal stateId As Integer) As Activity Implements IWorkflowCoreRuntime.GetContextActivityForId
            If Me.subStateMap.ContainsKey(stateId) Then
                Return Me.subStateMap.Item(stateId)
            End If
            Return Nothing
        End Function

        Private Function System.Workflow.ComponentModel.IWorkflowCoreRuntime.GetNewContextActivityId() As Integer Implements IWorkflowCoreRuntime.GetNewContextActivityId
            If Not ServiceEnvironment.IsInServiceThread(Me.InstanceId) Then
                Throw New InvalidOperationException(ExecutionStringManager.MustUseRuntimeThread)
            End If
            Return Me.GetNewContextId
        End Function

        Private Function System.Workflow.ComponentModel.IWorkflowCoreRuntime.GetService(ByVal activity As Activity, ByVal serviceType As Type) As Object Implements IWorkflowCoreRuntime.GetService
            If Not ServiceEnvironment.IsInServiceThread(Me.InstanceId) Then
                Throw New InvalidOperationException(ExecutionStringManager.MustUseRuntimeThread)
            End If
            If (serviceType Is GetType(IWorkflowCoreRuntime)) Then
                Return Me
            End If
            If (serviceType Is GetType(WorkflowRuntime)) Then
                Return Nothing
            End If
            If (serviceType Is GetType(WorkflowQueuingService)) Then
                Dim queuingService As WorkflowQueuingService = ServiceEnvironment.QueuingService
                If (queuingService Is Nothing) Then
                    queuingService = Me.qService
                End If
                queuingService.CallingActivity = ContextActivityUtils.ContextActivity(activity)
                Return queuingService
            End If
            If (serviceType Is GetType(IWorkflowDebuggerService)) Then
                Return Me._workflowDebuggerService
            End If
            Return Me.WorkflowRuntime.GetService(serviceType)
        End Function

        Private Function System.Workflow.ComponentModel.IWorkflowCoreRuntime.LoadContextActivity(ByVal contextInfo As ActivityExecutionContextInfo, ByVal outerActivity As Activity) As Activity Implements IWorkflowCoreRuntime.LoadContextActivity
            If Not ServiceEnvironment.IsInServiceThread(Me.InstanceId) Then
                Throw New InvalidOperationException(ExecutionStringManager.MustUseRuntimeThread)
            End If
            Dim activity As Activity = Nothing
            If Me.completedContextActivities.Contains(contextInfo) Then
                activity = DirectCast(Me.completedContextActivities.Item(contextInfo), Activity)
                Me.completedContextActivities.Remove(contextInfo)
                If (Not activity.Parent Is outerActivity.Parent) Then
                    activity.parent = outerActivity.Parent
                End If
                Return activity
            End If
            [Using] New RuntimeEnvironment(Me.WorkflowRuntime)
                activity = Me.WorkflowRuntime.WorkflowPersistenceService.LoadCompletedContextActivity(contextInfo.ContextGuid, outerActivity)
                If (activity Is Nothing) Then
                    Throw New InvalidOperationException(ExecutionStringManager.LoadContextActivityFailed)
                End If
            End [Using]
            Return activity
        End Function

        Private Sub System.Workflow.ComponentModel.IWorkflowCoreRuntime.OnAfterDynamicChange(ByVal updateSucceeded As Boolean, ByVal changes As IList([Of] WorkflowChangeAction)) Implements IWorkflowCoreRuntime.OnAfterDynamicChange
            If Not ServiceEnvironment.IsInServiceThread(Me.InstanceId) Then
                Throw New InvalidOperationException(ExecutionStringManager.MustUseRuntimeThread)
            End If
            Me.OnAfterDynamicChange(updateSucceeded, changes)
        End Sub

        Private Function System.Workflow.ComponentModel.IWorkflowCoreRuntime.OnBeforeDynamicChange(ByVal changes As IList([Of] WorkflowChangeAction)) As Boolean Implements IWorkflowCoreRuntime.OnBeforeDynamicChange
            If Not ServiceEnvironment.IsInServiceThread(Me.InstanceId) Then
                Throw New InvalidOperationException(ExecutionStringManager.MustUseRuntimeThread)
            End If
            Return Me.OnBeforeDynamicChange(changes)
        End Function

        Private Sub System.Workflow.ComponentModel.IWorkflowCoreRuntime.PersistInstanceState(ByVal activity As Activity) Implements IWorkflowCoreRuntime.PersistInstanceState
            If Not ServiceEnvironment.IsInServiceThread(Me.InstanceId) Then
                Throw New InvalidOperationException(ExecutionStringManager.MustUseRuntimeThread)
            End If
            Dim flag As Boolean = False
            If activity.UserData.Contains(GetType(PersistOnCloseAttribute)) Then
                flag = CBool(activity.UserData.Item(GetType(PersistOnCloseAttribute)))
            Else
                Dim customAttributes As Object() = activity.GetType.GetCustomAttributes(GetType(PersistOnCloseAttribute), True)
                If ((Not customAttributes Is Nothing) AndAlso (customAttributes.Length > 0)) Then
                    flag = True
                End If
            End If
            If (flag AndAlso (Me.WorkflowRuntime.GetService([Of] WorkflowPersistenceService) Is Nothing)) Then
                Throw New InvalidOperationException(String.Format(CultureInfo.CurrentCulture, ExecutionStringManager.MissingPersistenceServiceWithPersistOnClose, New Object() { activity.Name }))
            End If
            Me.ScheduleDelayedItems(activity)
            Dim unlock As Boolean = (activity.Parent Is Nothing)
            Dim needsCompensation As Boolean = False
            Me.Persist(activity, unlock, needsCompensation)
        End Sub

        Private Sub System.Workflow.ComponentModel.IWorkflowCoreRuntime.RaiseActivityExecuting(ByVal activity As Activity) Implements IWorkflowCoreRuntime.RaiseActivityExecuting
            If Not ServiceEnvironment.IsInServiceThread(Me.InstanceId) Then
                Throw New InvalidOperationException(ExecutionStringManager.MustUseRuntimeThread)
            End If
            Me.FireActivityExecuting(Me, activity)
        End Sub

        Private Sub System.Workflow.ComponentModel.IWorkflowCoreRuntime.RaiseException(ByVal e As Exception, ByVal activity As Activity, ByVal responsibleActivity As String) Implements IWorkflowCoreRuntime.RaiseException
            If Not ServiceEnvironment.IsInServiceThread(Me.InstanceId) Then
                Throw New InvalidOperationException(ExecutionStringManager.MustUseRuntimeThread)
            End If
            Me.ExceptionOccured(e, activity, responsibleActivity)
        End Sub

        Private Sub System.Workflow.ComponentModel.IWorkflowCoreRuntime.RaiseHandlerInvoked() Implements IWorkflowCoreRuntime.RaiseHandlerInvoked
            If Not ServiceEnvironment.IsInServiceThread(Me.InstanceId) Then
                Throw New InvalidOperationException(ExecutionStringManager.MustUseRuntimeThread)
            End If
            Me.FireWorkflowExecutionEvent(Me, WorkflowEventInternal.HandlerInvoked)
        End Sub

        Private Sub System.Workflow.ComponentModel.IWorkflowCoreRuntime.RaiseHandlerInvoking(ByVal handlerDelegate As Delegate) Implements IWorkflowCoreRuntime.RaiseHandlerInvoking
            If Not ServiceEnvironment.IsInServiceThread(Me.InstanceId) Then
                Throw New InvalidOperationException(ExecutionStringManager.MustUseRuntimeThread)
            End If
            Me.FireWorkflowHandlerInvokingEvent(Me, WorkflowEventInternal.HandlerInvoking, handlerDelegate)
        End Sub

        Private Sub System.Workflow.ComponentModel.IWorkflowCoreRuntime.RegisterContextActivity(ByVal activity As Activity) Implements IWorkflowCoreRuntime.RegisterContextActivity
            If Not ServiceEnvironment.IsInServiceThread(Me.InstanceId) Then
                Throw New InvalidOperationException(ExecutionStringManager.MustUseRuntimeThread)
            End If
            Me.RegisterDynamicActivity(activity, False)
        End Sub

        Private Sub System.Workflow.ComponentModel.IWorkflowCoreRuntime.RequestRevertToCheckpointState(ByVal currentActivity As Activity, ByVal callbackHandler As EventHandler([Of] EventArgs), ByVal callbackData As EventArgs, ByVal suspendOnRevert As Boolean, ByVal suspendInfo As String) Implements IWorkflowCoreRuntime.RequestRevertToCheckpointState
            If Not ServiceEnvironment.IsInServiceThread(Me.InstanceId) Then
                Throw New InvalidOperationException(ExecutionStringManager.MustUseRuntimeThread)
            End If
            Me.WorkflowStateRollbackService.RequestRevertToCheckpointState(currentActivity, callbackHandler, callbackData, suspendOnRevert, suspendInfo)
        End Sub

        Private Function System.Workflow.ComponentModel.IWorkflowCoreRuntime.Resume() As Boolean Implements IWorkflowCoreRuntime.Resume
            If Not ServiceEnvironment.IsInServiceThread(Me.InstanceId) Then
                Throw New InvalidOperationException(ExecutionStringManager.MustUseRuntimeThread)
            End If
            Return Me.ResumeOnIdle(False)
        End Function

        Private Sub System.Workflow.ComponentModel.IWorkflowCoreRuntime.SaveContextActivity(ByVal contextActivity As Activity) Implements IWorkflowCoreRuntime.SaveContextActivity
            If Not ServiceEnvironment.IsInServiceThread(Me.InstanceId) Then
                Throw New InvalidOperationException(ExecutionStringManager.MustUseRuntimeThread)
            End If
            Me.completedContextActivities.Add(DirectCast(contextActivity.GetValue(Activity.ActivityExecutionContextInfoProperty), ActivityExecutionContextInfo), contextActivity)
        End Sub

        Private Sub System.Workflow.ComponentModel.IWorkflowCoreRuntime.ScheduleItem(ByVal item As SchedulableItem, ByVal isInAtomicTransaction As Boolean, ByVal transacted As Boolean, ByVal queueInTransaction As Boolean) Implements IWorkflowCoreRuntime.ScheduleItem
            If Not ServiceEnvironment.IsInServiceThread(Me.InstanceId) Then
                Throw New InvalidOperationException(ExecutionStringManager.MustUseRuntimeThread)
            End If
            If Not queueInTransaction Then
                Me.Scheduler.ScheduleItem(item, isInAtomicTransaction, transacted)
            Else
                Me.AddItemToBeScheduledLater(Me.CurrentActivity, item)
            End If
        End Sub

        Private Function System.Workflow.ComponentModel.IWorkflowCoreRuntime.StartWorkflow(ByVal workflowType As Type, ByVal namedArgumentValues As Dictionary([Of] String, Object)) As Guid Implements IWorkflowCoreRuntime.StartWorkflow
            If Not ServiceEnvironment.IsInServiceThread(Me.InstanceId) Then
                Throw New InvalidOperationException(ExecutionStringManager.MustUseRuntimeThread)
            End If
            Dim empty As Guid = Guid.Empty
            Dim instance As WorkflowInstance = Me.WorkflowRuntime.InternalCreateWorkflow(New CreationContext(workflowType, Me, Me.CurrentActivity.QualifiedName, namedArgumentValues), Guid.NewGuid)
            If (Not instance Is Nothing) Then
                empty = instance.InstanceId
                instance.Start
            End If
            Return empty
        End Function

        Private Function System.Workflow.ComponentModel.IWorkflowCoreRuntime.SuspendInstance(ByVal suspendDescription As String) As Boolean Implements IWorkflowCoreRuntime.SuspendInstance
            If Not ServiceEnvironment.IsInServiceThread(Me.InstanceId) Then
                Throw New InvalidOperationException(ExecutionStringManager.MustUseRuntimeThread)
            End If
            Return Me.SuspendOnIdle(suspendDescription)
        End Function

        Private Sub System.Workflow.ComponentModel.IWorkflowCoreRuntime.TerminateInstance(ByVal e As Exception) Implements IWorkflowCoreRuntime.TerminateInstance
            If Not ServiceEnvironment.IsInServiceThread(Me.InstanceId) Then
                Throw New InvalidOperationException(ExecutionStringManager.MustUseRuntimeThread)
            End If
            Me.ThrownException = e
            Me.TerminateOnIdle(WorkflowExecutor.GetNestedExceptionMessage(e))
        End Sub

        Private Sub System.Workflow.ComponentModel.IWorkflowCoreRuntime.Track(ByVal key As String, ByVal args As Object) Implements IWorkflowCoreRuntime.Track
            If Not ServiceEnvironment.IsInServiceThread(Me.InstanceId) Then
                Throw New InvalidOperationException(ExecutionStringManager.MustUseRuntimeThread)
            End If
            Me.Track(Me.CurrentActivity, key, args)
        End Sub

        Private Sub System.Workflow.ComponentModel.IWorkflowCoreRuntime.UnregisterContextActivity(ByVal activity As Activity) Implements IWorkflowCoreRuntime.UnregisterContextActivity
            If Not ServiceEnvironment.IsInServiceThread(Me.InstanceId) Then
                Throw New InvalidOperationException(ExecutionStringManager.MustUseRuntimeThread)
            End If
            Me.UnregisterDynamicActivity(activity)
        End Sub

        Friend Sub Terminate(ByVal [error] As String)
            WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 0, "Workflow Runtime: WorkflowExecutor::Terminate : Got a terminate request for instance {0}", New Object() { Me.InstanceIdString })
            Try 
                [Using] New ScheduleWork(Me, True)
                    [Using] Me._executorLock.Enter
                        Me.Scheduler.AbortOrTerminateRequested = True
                        Me.Scheduler.CanRun = False
                        [Using] New SchedulerLockGuard(Me._schedulerLock, Me)
                            [Using] New ServiceEnvironment(Me.rootActivity)
                                If Not Me.IsInstanceValid Then
                                    Throw New InvalidOperationException(ExecutionStringManager.WorkflowNotValid)
                                End If
                                Me.TerminateOnIdle([error])
                            End [Using]
                        End [Using]
                    End [Using]
                End [Using]
            Catch exception As Exception
                WorkflowTrace.Runtime.TraceEvent(TraceEventType.Error, 0, "Workflow Runtime: WorkflowExecutor: Terminate attempt on instance '{0}' threw an exception '{1}' at {2}", New Object() { Me.InstanceIdString, exception.Message, exception.StackTrace })
                Throw
            End Try
        End Sub

        Friend Function TerminateOnIdle(ByVal [error] As String) As Boolean
            If Not Me.IsInstanceValid Then
                Return False
            End If
            Me.Scheduler.CanRun = False
            Try 
                WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 0, "Workflow Runtime: WorkflowExecutor: Terminating instance {0}", New Object() { Me.InstanceIdString })
                If (Not Me.ThrownException Is Nothing) Then
                    Me.FireWorkflowTerminating(Me.ThrownException)
                Else
                    Me.FireWorkflowTerminating([error])
                End If
                Me.stateChangedSincePersistence = True
                Dim workflowStatus As WorkflowStatus = Me.WorkflowStatus
                Me.rootActivity.SetValue(WorkflowExecutor.SuspendOrTerminateInfoProperty, [error])
                Me.WorkflowStatus = WorkflowStatus.Terminated
                [Using] Me._msgDeliveryLock.Enter
                    Me.TimerQueue.SuspendDelivery
                    Me.rootActivity.SetValue(Activity.ExecutionResultProperty, ActivityExecutionResult.Canceled)
                    Try 
                        Me.Persist(Me.rootActivity, True, False)
                    Catch exception As Exception
                        Me.WorkflowStatus = workflowStatus
                        Me.rootActivity.SetValue(Activity.ExecutionResultProperty, ActivityExecutionResult.None)
                        WorkflowTrace.Runtime.TraceEvent(TraceEventType.Error, 0, "Workflow Runtime: WorkflowExecutor: Persistence attempt at instance '{0}' termination threw an exception. Aborting the instance. The termination event would be raised. The instance would execute from the last persisted point whenever started by the host explicitly. Exception:{1}" & ChrW(10) & "{2}", New Object() { Me.InstanceIdString, exception.Message, exception.StackTrace })
                        Me.AbortOnIdle
                        Return False
                    End Try
                    Me.qService.MoveAllMessagesToPendingQueue
                    If (Not Me.ThrownException Is Nothing) Then
                        Me.FireEventAfterSchedulerLockDrop(WorkflowEventInternal.Terminated, Me.ThrownException)
                    Else
                        Me.FireEventAfterSchedulerLockDrop(WorkflowEventInternal.Terminated, [error])
                    End If
                    Me.IsInstanceValid = False
                End [Using]
                If (Not Me.currentAtomicActivity Is Nothing) Then
                    Me.atomicActivityEvent.Set
                    Me.atomicActivityEvent.Close
                End If
            Catch exception2 As Exception
                If ((Me.rootActivity Is Me.CurrentActivity) AndAlso (Me.rootActivity.ExecutionStatus = ActivityExecutionStatus.Closed)) Then
                    [Using] Me._msgDeliveryLock.Enter
                        Me.AbortOnIdle
                        Return False
                    End [Using]
                End If
                Me.Scheduler.CanRun = True
                Throw
            End Try
            Return True
        End Function

        Friend Sub Track(ByVal activity As Activity, ByVal key As String, ByVal args As Object)
            Me.FireUserTrackPoint(activity, key, args)
        End Sub

        Friend Function TryUnload() As Boolean
            WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 0, "Workflow Runtime: WorkflowExecutor: Got a TryUnload request for instance {0}", New Object() { Me.InstanceIdString })
            Try 
                If Not Me.IsInstanceValid Then
                    Return False
                End If
                If (Me.WorkflowRuntime.WorkflowPersistenceService Is Nothing) Then
                    Dim message As String = String.Format(CultureInfo.CurrentCulture, ExecutionStringManager.MissingPersistenceService, New Object() { Me.InstanceId })
                    WorkflowTrace.Runtime.TraceEvent(TraceEventType.Error, 0, message)
                    Throw New InvalidOperationException(message)
                End If
                [Using] New ScheduleWork(Me, True)
                    If Me._executorLock.TryEnter Then
                        Try 
                            If Me._schedulerLock.TryEnter Then
                                Try 
                                    If Me._msgDeliveryLock.TryEnter Then
                                        [Using] New ServiceEnvironment(Me.rootActivity)
                                            Try 
                                                If Me.IsInstanceValid Then
                                                    Me.ProcessQueuedEvents
                                                    If Me.IsUnloadableNow Then
                                                        Return Me.PerformUnloading(False)
                                                    End If
                                                End If
                                                Return False
                                            Finally
                                                Me._msgDeliveryLock.Exit
                                            End Try
                                        End [Using]
                                    End If
                                Finally
                                    SchedulerLockGuard.Exit(Me._schedulerLock, Me)
                                End Try
                            End If
                        Finally
                            Me._executorLock.Exit
                        End Try
                    End If
                End [Using]
            Catch exception As Exception
                WorkflowTrace.Runtime.TraceEvent(TraceEventType.Error, 0, "Workflow Runtime: WorkflowExecutor: TryUnloading attempt on instance '{0}' threw an exception '{1}' at {2}", New Object() { Me.InstanceIdString, exception.Message, exception.StackTrace })
                Throw
            End Try
            Return False
        End Function

        Friend Sub Unload()
            WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 0, "Workflow Runtime: WorkflowExecutor: Got an unload request for instance {0}", New Object() { Me.InstanceIdString })
            Try 
                [Using] New ScheduleWork(Me, True)
                    [Using] Me._executorLock.Enter
                        If (Me.WorkflowRuntime.WorkflowPersistenceService Is Nothing) Then
                            Dim message As String = String.Format(CultureInfo.CurrentCulture, ExecutionStringManager.MissingPersistenceService, New Object() { Me.InstanceId })
                            WorkflowTrace.Runtime.TraceEvent(TraceEventType.Error, 0, message)
                            Throw New InvalidOperationException(message)
                        End If
                        Me.Scheduler.CanRun = False
                        [Using] New SchedulerLockGuard(Me._schedulerLock, Me)
                            [Using] New ServiceEnvironment(Me.rootActivity)
                                If Not Me.IsInstanceValid Then
                                    Throw New InvalidOperationException(ExecutionStringManager.WorkflowNotValid)
                                End If
                                If (Not Me.currentAtomicActivity Is Nothing) Then
                                    Me.Scheduler.CanRun = True
                                    Throw New ExecutorLocksHeldException(Me.atomicActivityEvent)
                                End If
                                WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 0, (Me.InstanceId & ": Calling PerformUnloading(false) on instance {0} hc {1}"), New Object() { Me.InstanceIdString, Me.GetHashCode })
                                Me.PerformUnloading(False)
                                WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 0, (Me.InstanceId & ": Returning from PerformUnloading(false): IsInstanceValue: " & Me.IsInstanceValid))
                            End [Using]
                        End [Using]
                    End [Using]
                End [Using]
            Catch exception As Exception
                WorkflowTrace.Runtime.TraceEvent(TraceEventType.Error, 0, "Workflow Runtime: WorkflowExecutor: Unload attempt on instance '{0}' threw an exception '{1}' at {2}", New Object() { Me.InstanceIdString, exception.Message, exception.StackTrace })
                Throw
            End Try
        End Sub

        Friend Sub UnregisterDynamicActivity(ByVal dynamicActivity As Activity)
            Dim key As Integer = ContextActivityUtils.ContextId(dynamicActivity)
            Me.subStateMap.Remove(key)
            WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 0, "Removing context {0}:{1}", New Object() { key, dynamicActivity.QualifiedName })
            dynamicActivity.OnActivityExecutionContextUnload(Me)
        End Sub


        ' Properties
        Friend ReadOnly Property AdditionalInformation As String
            Get
                Return CStr(Me.rootActivity.GetValue(WorkflowExecutor.SuspendOrTerminateInfoProperty))
            End Get
        End Property

        Friend ReadOnly Property BatchCollection As WorkBatchCollection
            Get
                Return Me._resourceManager.BatchCollection
            End Get
        End Property

        Friend Property CompletedContextActivities As Hashtable
            Get
                Return Me.completedContextActivities
            End Get
            Set(ByVal value As Hashtable)
                Me.completedContextActivities = value
            End Set
        End Property

        Friend Property CurrentActivity As Activity
            Get
                Return Me._lastExecutingActivity
            End Get
            Set(ByVal value As Activity)
                Me._lastExecutingActivity = value
            End Set
        End Property

        Friend ReadOnly Property EventsToFireList As List([Of] SchedulerLockGuardInfo)
            Get
                Return Me.eventsToFireList
            End Get
        End Property

        Friend ReadOnly Property ExecutorLock As InstanceLock
            Get
                Return Me._executorLock
            End Get
        End Property

        Friend ReadOnly Property ID As Guid
            Get
                Return Me.InstanceId
            End Get
        End Property

        Property InstanceId As Guid
            Friend Get
                Return Me.workflowInstanceId
            End Get
            Private Set(ByVal value As Guid)
                Me.workflowInstanceId = value
            End Set
        End Property

        Friend ReadOnly Property InstanceIdString As String
            Get
                If (Me.workflowIdString Is Nothing) Then
                    Me.workflowIdString = Me.InstanceId.ToString
                End If
                Return Me.workflowIdString
            End Get
        End Property

        Friend Property IsIdle As Boolean
            Get
                Return Me.isInstanceIdle
            End Get
            Set(ByVal value As Boolean)
                [Using] guard As InstanceLockGuard = Me.MessageDeliveryLock.Enter
                    Try 
                        Me.isInstanceIdle = value
                        Me.RootActivity.SetValue(WorkflowExecutor.IsIdleProperty, value)
                    Finally
                        If Me.IsIdle Then
                            guard.Pulse
                        End If
                    End Try
                End [Using]
            End Set
        End Property

        Friend Property IsInstanceValid As Boolean
            Get
                Return Me._isInstanceValid
            End Get
            Set(ByVal value As Boolean)
                If Not value Then
                    Me.ResourceManager.ClearAllBatchedWork
                End If
                Me._isInstanceValid = value
            End Set
        End Property

        Friend ReadOnly Property IsUnloadableNow As Boolean
            Get
                If (Not Me.currentAtomicActivity Is Nothing) Then
                    Return False
                End If
                If Not Me.Scheduler.IsStalledNow Then
                    Return (Me.WorkflowStatus = WorkflowStatus.Suspended)
                End If
                Return True
            End Get
        End Property

        Friend ReadOnly Property MessageDeliveryLock As InstanceLock
            Get
                Return Me._msgDeliveryLock
            End Get
        End Property

        Friend ReadOnly Property ResourceManager As VolatileResourceManager
            Get
                Return Me._resourceManager
            End Get
        End Property

        Friend ReadOnly Property RootActivity As Activity
            Get
                Return Me.rootActivity
            End Get
        End Property

        Friend ReadOnly Property Scheduler As Scheduler
            Get
                Return Me.schedulingContext
            End Get
        End Property

        Private ReadOnly Property System.Workflow.ComponentModel.IWorkflowCoreRuntime.CurrentActivity As Activity
            Get
                If Not ServiceEnvironment.IsInServiceThread(Me.InstanceId) Then
                    Throw New InvalidOperationException(ExecutionStringManager.MustUseRuntimeThread)
                End If
                Return Me.CurrentActivity
            End Get
        End Property

        Private ReadOnly Property System.Workflow.ComponentModel.IWorkflowCoreRuntime.CurrentAtomicActivity As Activity
            Get
                Return Me.currentAtomicActivity
            End Get
        End Property

        Private ReadOnly Property System.Workflow.ComponentModel.IWorkflowCoreRuntime.InstanceID As Guid
            Get
                If Not ServiceEnvironment.IsInServiceThread(Me.InstanceId) Then
                    Throw New InvalidOperationException(ExecutionStringManager.MustUseRuntimeThread)
                End If
                Return Me.InstanceId
            End Get
        End Property

        Private ReadOnly Property System.Workflow.ComponentModel.IWorkflowCoreRuntime.IsDynamicallyUpdated As Boolean
            Get
                Return (Not Me.WorkflowDefinition.GetValue(WorkflowChanges.WorkflowChangeActionsProperty) Is Nothing)
            End Get
        End Property

        Private ReadOnly Property System.Workflow.ComponentModel.IWorkflowCoreRuntime.RootActivity As Activity
            Get
                Return Me.rootActivity
            End Get
        End Property

        Friend Property ThrownException As Exception
            Get
                Return Me.thrownException
            End Get
            Set(ByVal value As Exception)
                Me.thrownException = value
            End Set
        End Property

        Property TimerQueue As TimerEventSubscriptionCollection
            Friend Get
                If (Me._timerQueue Is Nothing) Then
                    Me._timerQueue = DirectCast(Me.rootActivity.GetValue(TimerEventSubscriptionCollection.TimerCollectionProperty), TimerEventSubscriptionCollection)
                End If
                Return Me._timerQueue
            End Get
            Private Set(ByVal value As TimerEventSubscriptionCollection)
                Me._timerQueue = value
                Me.rootActivity.SetValue(TimerEventSubscriptionCollection.TimerCollectionProperty, Me._timerQueue)
            End Set
        End Property

        Friend ReadOnly Property TrackingCallingState As TrackingCallingState
            Get
                Return DirectCast(Me.rootActivity.GetValue(WorkflowExecutor.TrackingCallingStateProperty), TrackingCallingState)
            End Get
        End Property

        Friend ReadOnly Property WorkflowDefinition As Activity
            Get
                Return Me._workflowDefinition
            End Get
        End Property

        Friend ReadOnly Property WorkflowInstance As WorkflowInstance
            Get
                Return Me._workflowInstance
            End Get
        End Property

        Friend ReadOnly Property WorkflowRuntime As WorkflowRuntime
            Get
                Return Me._runtime
            End Get
        End Property

        Friend ReadOnly Property WorkflowStateRollbackService As WorkflowStateRollbackService
            Get
                If (Me.workflowStateRollbackService Is Nothing) Then
                    Me.workflowStateRollbackService = New WorkflowStateRollbackService(Me)
                End If
                Return Me.workflowStateRollbackService
            End Get
        End Property

        Property WorkflowStatus As WorkflowStatus
            Friend Get
                Return DirectCast(Me.rootActivity.GetValue(WorkflowExecutor.WorkflowStatusProperty), WorkflowStatus)
            End Get
            Private Set(ByVal value As WorkflowStatus)
                Me.rootActivity.SetValue(WorkflowExecutor.WorkflowStatusProperty, value)
            End Set
        End Property


        ' Fields
        Private _executorLock As InstanceLock
        Private _isInstanceValid As Boolean = False
        Private _lastExecutingActivity As Activity
        Private _msgDeliveryLock As InstanceLock
        Private _resourceManager As VolatileResourceManager = New VolatileResourceManager
        Private _runtime As WorkflowRuntime
        Private _schedulerLock As InstanceLock
        Private _timerQueue As TimerEventSubscriptionCollection
        Private _workflowDebuggerService As WorkflowDebuggerService
        Private _workflowDefinition As Activity ModReq(IsVolatile)
        Private _workflowInstance As WorkflowInstance
        Private activityThrowingException As String
        Private atomicActivityEvent As ManualResetEvent
        Private attemptedRootAECUnload As Boolean
        Private attemptedRootDispose As Boolean
        Private completedContextActivities As Hashtable = New Hashtable
        Private Shared ContextIdProperty As DependencyProperty = DependencyProperty.RegisterAttached("ContextId", GetType(Integer), GetType(WorkflowExecutor), New PropertyMetadata(0))
        Friend currentAtomicActivity As Activity
        Private Shared disableWorkflowDebugging As BooleanSwitch = New BooleanSwitch("DisableWorkflowDebugging", "Disables workflow debugging in host")
        Private eventsToFireList As List([Of] SchedulerLockGuardInfo) = New List([Of] SchedulerLockGuardInfo)
        Friend Shared ReadOnly IsBlockedProperty As DependencyProperty = DependencyProperty.RegisterAttached("IsBlocked", GetType(Boolean), GetType(WorkflowExecutor), New PropertyMetadata(False))
        Private Shared IsIdleProperty As DependencyProperty = DependencyProperty.RegisterAttached("IsIdle", GetType(Boolean), GetType(WorkflowExecutor), New PropertyMetadata(False))
        Private isInstanceIdle As Boolean
        Private Shared IsSuspensionRequestedProperty As DependencyProperty = DependencyProperty.RegisterAttached("IsSuspensionRequested", GetType(Boolean), GetType(WorkflowExecutor), New PropertyMetadata(False))
        Private qService As WorkflowQueuingService
        Private rootActivity As Activity
        Private schedulingContext As Scheduler
        Friend stateChangedSincePersistence As Boolean
        <NonSerialized> _
        Private subStateMap As Dictionary([Of] Integer, Activity) = New Dictionary([Of] Integer, Activity)
        Friend Shared ReadOnly SuspendOrTerminateInfoProperty As DependencyProperty = DependencyProperty.RegisterAttached("SuspendOrTerminateInfo", GetType(String), GetType(WorkflowExecutor))
        Private thrownException As Exception
        Private Shared TrackingCallingStateProperty As DependencyProperty = DependencyProperty.RegisterAttached("TrackingCallingState", GetType(TrackingCallingState), GetType(WorkflowExecutor))
        Friend Shared TrackingListenerBrokerProperty As DependencyProperty = DependencyProperty.RegisterAttached("TrackingListenerBroker", GetType(TrackingListenerBroker), GetType(WorkflowExecutor))
        Friend Shared ReadOnly TransactionalPropertiesProperty As DependencyProperty = DependencyProperty.RegisterAttached("TransactionalProperties", GetType(TransactionalProperties), GetType(WorkflowExecutor), New PropertyMetadata(DependencyPropertyOptions.NonSerialized))
        Friend Shared ReadOnly TransientBatchProperty As DependencyProperty = DependencyProperty.RegisterAttached("TransientBatch", GetType(IWorkBatch), GetType(WorkflowExecutor), New PropertyMetadata(Nothing, DependencyPropertyOptions.NonSerialized, New GetValueOverride(AddressOf WorkflowExecutor.GetTransientBatch), Nothing))
        Private Shared workflowDebuggingDisabled As Boolean
        Friend Shared ReadOnly WorkflowExecutorProperty As DependencyProperty = DependencyProperty.RegisterAttached("WorkflowExecutor", GetType(WorkflowExecutor), GetType(WorkflowExecutor), New PropertyMetadata(DependencyPropertyOptions.NonSerialized))
        Private workflowIdString As String
        Private workflowInstanceId As Guid
        Friend Shared ReadOnly WorkflowInstanceIdProperty As DependencyProperty = DependencyProperty.RegisterAttached("WorkflowInstanceId", GetType(Guid), GetType(WorkflowExecutor), New PropertyMetadata(Guid.NewGuid))
        Private workflowStateRollbackService As WorkflowStateRollbackService
        Friend Shared ReadOnly WorkflowStatusProperty As DependencyProperty = DependencyProperty.RegisterAttached("WorkflowStatus", GetType(WorkflowStatus), GetType(WorkflowExecutor), New PropertyMetadata(WorkflowStatus.Created))

        ' Nested Types
        Friend Class ActivityExecutingEventArgs
            Inherits WorkflowExecutionEventArgs
            ' Methods
            Friend Sub New(ByVal activity As Activity)
                Me._activity = activity
                MyBase._eventType = WorkflowEventInternal.ActivityExecuting
            End Sub


            ' Properties
            Friend ReadOnly Property Activity As Activity
                Get
                    Return Me._activity
                End Get
            End Property


            ' Fields
            Private _activity As Activity
        End Class

        Friend Class ActivityStatusChangeEventArgs
            Inherits WorkflowExecutionEventArgs
            ' Methods
            Friend Sub New(ByVal activity As Activity)
                Me._activity = activity
                MyBase._eventType = WorkflowEventInternal.ActivityStatusChange
            End Sub


            ' Properties
            Friend ReadOnly Property Activity As Activity
                Get
                    Return Me._activity
                End Get
            End Property


            ' Fields
            Private _activity As Activity
        End Class

        Friend Class DynamicUpdateEventArgs
            Inherits WorkflowExecutionEventArgs
            ' Methods
            Friend Sub New(ByVal changeActions As IList([Of] WorkflowChangeAction), ByVal eventType As WorkflowEventInternal)
                Me._changeActions = changeActions
                MyBase._eventType = eventType
            End Sub


            ' Properties
            Friend ReadOnly Property ChangeActions As IList([Of] WorkflowChangeAction)
                Get
                    Return Me._changeActions
                End Get
            End Property


            ' Fields
            Private _changeActions As IList([Of] WorkflowChangeAction) = New List([Of] WorkflowChangeAction)
        End Class

        Private Class ResetCurrentActivity
            Implements IDisposable
            ' Methods
            Friend Sub New(ByVal workflowExecutor As WorkflowExecutor, ByVal oldCurrentActivity As Activity)
                Me.workflowExecutor = workflowExecutor
                Me.oldCurrentActivity = oldCurrentActivity
            End Sub

            Private Sub System.IDisposable.Dispose() Implements IDisposable.Dispose
                Me.workflowExecutor.CurrentActivity = Me.oldCurrentActivity
            End Sub


            ' Fields
            Private oldCurrentActivity As Activity
            Private workflowExecutor As WorkflowExecutor
        End Class

        Friend Class UserTrackPointEventArgs
            Inherits WorkflowExecutionEventArgs
            ' Methods
            Friend Sub New(ByVal activity As Activity, ByVal key As String, ByVal args As Object)
                If (activity Is Nothing) Then
                    Throw New ArgumentNullException("activity")
                End If
                Me._activity = activity
                Me._args = args
                MyBase._eventType = WorkflowEventInternal.UserTrackPoint
                Me._key = key
            End Sub


            ' Properties
            Friend ReadOnly Property Activity As Activity
                Get
                    Return Me._activity
                End Get
            End Property

            Friend ReadOnly Property Args As Object
                Get
                    Return Me._args
                End Get
            End Property

            Friend ReadOnly Property Key As String
                Get
                    Return Me._key
                End Get
            End Property


            ' Fields
            Private _activity As Activity
            Private _args As Object
            Private _key As String
        End Class

        Friend Class WorkflowExecutionEventArgs
            Inherits EventArgs
            ' Methods
            Protected Sub New()
            End Sub

            Friend Sub New(ByVal eventType As WorkflowEventInternal)
                Me._eventType = eventType
            End Sub


            ' Properties
            Friend ReadOnly Property EventType As WorkflowEventInternal
                Get
                    Return Me._eventType
                End Get
            End Property


            ' Fields
            Protected _eventType As WorkflowEventInternal
        End Class

        Friend Class WorkflowExecutionExceptionEventArgs
            Inherits WorkflowExecutionEventArgs
            ' Methods
            Friend Sub New(ByVal exception As Exception, ByVal currentPath As String, ByVal originalPath As String, ByVal contextGuid As Guid, ByVal parentContextGuid As Guid)
                If (exception Is Nothing) Then
                    Throw New ArgumentNullException("exception")
                End If
                Me._exception = exception
                Me._currentPath = currentPath
                Me._originalPath = originalPath
                MyBase._eventType = WorkflowEventInternal.Exception
                Me._contextGuid = contextGuid
                Me._parentContextGuid = parentContextGuid
            End Sub


            ' Properties
            Friend ReadOnly Property ContextGuid As Guid
                Get
                    Return Me._contextGuid
                End Get
            End Property

            Friend ReadOnly Property CurrentPath As String
                Get
                    Return Me._currentPath
                End Get
            End Property

            Friend ReadOnly Property Exception As Exception
                Get
                    Return Me._exception
                End Get
            End Property

            Friend ReadOnly Property OriginalPath As String
                Get
                    Return Me._originalPath
                End Get
            End Property

            Friend ReadOnly Property ParentContextGuid As Guid
                Get
                    Return Me._parentContextGuid
                End Get
            End Property


            ' Fields
            Private _contextGuid As Guid
            Private _currentPath As String
            Private _exception As Exception
            Private _originalPath As String
            Private _parentContextGuid As Guid
        End Class

        Friend NotInheritable Class WorkflowExecutionSuspendedEventArgs
            Inherits WorkflowExecutionEventArgs
            ' Methods
            Friend Sub New(ByVal [error] As String)
                MyBase._eventType = WorkflowEventInternal.Suspended
                Me._error = [error]
            End Sub


            ' Properties
            Friend ReadOnly Property [Error] As String
                Get
                    Return Me._error
                End Get
            End Property


            ' Fields
            Private _error As String
        End Class

        Friend NotInheritable Class WorkflowExecutionSuspendingEventArgs
            Inherits WorkflowExecutionEventArgs
            ' Methods
            Friend Sub New(ByVal [error] As String)
                MyBase._eventType = WorkflowEventInternal.Suspending
                Me._error = [error]
            End Sub


            ' Properties
            Friend ReadOnly Property [Error] As String
                Get
                    Return Me._error
                End Get
            End Property


            ' Fields
            Private _error As String
        End Class

        Friend NotInheritable Class WorkflowExecutionTerminatedEventArgs
            Inherits WorkflowExecutionEventArgs
            ' Methods
            Friend Sub New(ByVal exception As Exception)
                Me._exception = exception
                MyBase._eventType = WorkflowEventInternal.Terminated
            End Sub

            Friend Sub New(ByVal [error] As String)
                Me._error = [error]
                MyBase._eventType = WorkflowEventInternal.Terminated
            End Sub


            ' Properties
            Friend ReadOnly Property [Error] As String
                Get
                    Return Me._error
                End Get
            End Property

            Friend ReadOnly Property Exception As Exception
                Get
                    Return Me._exception
                End Get
            End Property


            ' Fields
            Private _error As String
            Private _exception As Exception
        End Class

        Friend NotInheritable Class WorkflowExecutionTerminatingEventArgs
            Inherits WorkflowExecutionEventArgs
            ' Methods
            Friend Sub New(ByVal exception As Exception)
                If (exception Is Nothing) Then
                    Throw New ArgumentNullException("exception")
                End If
                Me._exception = exception
                MyBase._eventType = WorkflowEventInternal.Terminating
            End Sub

            Friend Sub New(ByVal [error] As String)
                Me._error = [error]
                MyBase._eventType = WorkflowEventInternal.Terminating
            End Sub


            ' Properties
            Friend ReadOnly Property [Error] As String
                Get
                    Return Me._error
                End Get
            End Property

            Friend ReadOnly Property Exception As Exception
                Get
                    Return Me._exception
                End Get
            End Property


            ' Fields
            Private _error As String
            Private _exception As Exception
        End Class

        Friend Class WorkflowHandlerInvokingEventArgs
            Inherits WorkflowExecutionEventArgs
            ' Methods
            Friend Sub New(ByVal eventType As WorkflowEventInternal, ByVal delegateHandler As Delegate)
                MyBase.New(eventType)
                Me._delegateHandler = delegateHandler
            End Sub


            ' Properties
            Friend ReadOnly Property DelegateMethod As Delegate
                Get
                    Return Me._delegateHandler
                End Get
            End Property


            ' Fields
            Private _delegateHandler As Delegate
        End Class
    End Class
End Namespace

